diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/gspca/mr97310a.c | 98 |
1 files changed, 45 insertions, 53 deletions
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c index db2f84e635c5..3bdf064699e9 100644 --- a/drivers/media/video/gspca/mr97310a.c +++ b/drivers/media/video/gspca/mr97310a.c @@ -64,11 +64,9 @@ struct sd { u8 cam_type; /* 0 is CIF and 1 is VGA */ u8 sensor_type; /* We use 0 and 1 here, too. */ u8 do_lcd_stop; - u8 regs[15]; int brightness; u16 exposure; - u8 autogain; u8 gain; }; @@ -85,10 +83,14 @@ static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); +static void setbrightness(struct gspca_dev *gspca_dev); +static void setexposure(struct gspca_dev *gspca_dev); +static void setgain(struct gspca_dev *gspca_dev); /* V4L2 controls supported by the driver */ static struct ctrl sd_ctrls[] = { { +#define BRIGHTNESS_IDX 0 { .id = V4L2_CID_BRIGHTNESS, .type = V4L2_CTRL_TYPE_INTEGER, @@ -103,6 +105,7 @@ static struct ctrl sd_ctrls[] = { .get = sd_getbrightness, }, { +#define EXPOSURE_IDX 1 { .id = V4L2_CID_EXPOSURE, .type = V4L2_CTRL_TYPE_INTEGER, @@ -117,6 +120,7 @@ static struct ctrl sd_ctrls[] = { .get = sd_getexposure, }, { +#define GAIN_IDX 2 { .id = V4L2_CID_GAIN, .type = V4L2_CTRL_TYPE_INTEGER, @@ -360,14 +364,24 @@ static int sd_config(struct gspca_dev *gspca_dev, cam = &gspca_dev->cam; cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); - sd->cam_type = CAM_TYPE_VGA; + PDEBUG(D_PROBE, "MR97310A camera detected" " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); + if (id->idProduct == 0x010e) { - cam->nmodes--; sd->cam_type = CAM_TYPE_CIF; + cam->nmodes--; + } else { + sd->cam_type = CAM_TYPE_VGA; + gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX) | + (1 << EXPOSURE_IDX) | (1 << GAIN_IDX); } + + sd->brightness = MR97310A_BRIGHTNESS_DEFAULT; + sd->exposure = MR97310A_EXPOSURE_DEFAULT; + sd->gain = MR97310A_GAIN_DEFAULT; + return 0; } @@ -377,35 +391,6 @@ static int sd_init(struct gspca_dev *gspca_dev) return 0; } -static int adjust_cif_sensor(struct gspca_dev *gspca_dev) -{ - /* - * FIXME: The following sequence resets brightness, contrast, and - * related settings. Some of the values are adjustable, presumably - * based upon what is detected in the frames. Here, only some - * vaules are used which are compromises. When more is known about - * what is done here, this needs to be moved out to presently - * nonexistent functions which do controls. The same control messages - * do work for all of the CIF cameras. - */ - - const struct sensor_w_data cif_sensor1_adjust_data[] = { - {0x02, 0x01, {0x10, 0x12, 0x0a}, 3}, - /* Last or possibly two last bytes adjustable, above. */ - {0x13, 0x04, {0x01}, 1}, /* seems to mean "write" */ - {0x05, 0x01, {0x22, 0x00, 0x81, 0x06}, 4}, - /* Last or possibly two last bytes adjustable, above. */ - {0x13, 0x04, {0x01}, 1}, - {0x09, 0x02, {0x05, 0x00, 0x00, 0x05, 0x07, 0x16}, 6}, - /* Last or possibly two last bytes adjustable, above. */ - {0x13, 0x04, {0x01}, 1}, - {0, 0, {0}, 0} - }; - - return sensor_write_regs(gspca_dev, cif_sensor1_adjust_data, - ARRAY_SIZE(cif_sensor1_adjust_data)); -} - static int start_cif_cam(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -452,6 +437,11 @@ static int start_cif_cam(struct gspca_dev *gspca_dev) sd->sensor_type = 1; PDEBUG(D_ERR, "Sensor type is %01x", sd->sensor_type); + + if (sd->sensor_type == 0) + gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX) | + (1 << EXPOSURE_IDX) | (1 << GAIN_IDX); + memcpy(data, startup_string, 11); if (sd->sensor_type) data[5] = 0xbb; @@ -504,18 +494,15 @@ static int start_cif_cam(struct gspca_dev *gspca_dev) ARRAY_SIZE(cif_sensor0_init_data)); } else { /* sd->sensor_type = 1 */ const struct sensor_w_data cif_sensor1_init_data[] = { + /* Reg 3,4, 7,8 get set by the controls */ {0x02, 0x00, {0x10}, 1}, - {0x03, 0x01, {0x12}, 1}, - {0x04, 0x01, {0x05}, 1}, - {0x05, 0x01, {0x65}, 1}, - {0x06, 0x01, {0x32}, 1}, - {0x07, 0x01, {0x00}, 1}, - {0x08, 0x02, {0x06}, 1}, + {0x05, 0x01, {0x22}, 1}, /* 5/6 also seen as 65h/32h */ + {0x06, 0x01, {0x00}, 1}, {0x09, 0x02, {0x0e}, 1}, {0x0a, 0x02, {0x05}, 1}, {0x0b, 0x02, {0x05}, 1}, {0x0c, 0x02, {0x0f}, 1}, - {0x0d, 0x02, {0x00}, 1}, + {0x0d, 0x02, {0x07}, 1}, {0x0e, 0x02, {0x0c}, 1}, {0x0f, 0x00, {0x00}, 1}, {0x10, 0x00, {0x06}, 1}, @@ -530,19 +517,18 @@ static int start_cif_cam(struct gspca_dev *gspca_dev) if (err_code < 0) return err_code; + setbrightness(gspca_dev); + setexposure(gspca_dev); + setgain(gspca_dev); + msleep(200); + data[0] = 0x00; data[1] = 0x4d; /* ISOC transfering enable... */ err_code = mr_write(gspca_dev, 2); if (err_code < 0) return err_code; - msleep(200); - err_code = adjust_cif_sensor(gspca_dev); - if (err_code < 0) - return err_code; - - msleep(200); return 0; } @@ -711,11 +697,6 @@ static int sd_start(struct gspca_dev *gspca_dev) int err_code; struct cam *cam; - /* TEST TEST */ - int i; - for (i = 2; i <= 14; i++) - sd->regs[i] = sd_ctrls[i - 2].qctrl.default_value; - cam = &gspca_dev->cam; sd->sof_read = 0; /* @@ -760,11 +741,16 @@ static void setbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; u8 val; + + if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS_IDX)) + return; + + /* Note register 7 is also seen as 0x8x or 0xCx in dumps */ if (sd->brightness > 0) { - sensor_write1(gspca_dev, 7, 0); + sensor_write1(gspca_dev, 7, 0x00); val = sd->brightness; } else { - sensor_write1(gspca_dev, 7, 1); + sensor_write1(gspca_dev, 7, 0x01); val = 257 - sd->brightness; } sensor_write1(gspca_dev, 8, val); @@ -775,6 +761,9 @@ static void setexposure(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; u8 val; + if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX)) + return; + val = sd->exposure >> 4; sensor_write1(gspca_dev, 3, val); val = sd->exposure & 0xf; @@ -785,6 +774,9 @@ static void setgain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; + if (gspca_dev->ctrl_dis & (1 << GAIN_IDX)) + return; + sensor_write1(gspca_dev, 3, sd->gain); } |