Commit 9ac6978a authored by Hans de Goede's avatar Hans de Goede Committed by Mauro Carvalho Chehab

V4L/DVB (12620): gspca_mr97310a: cleanup/fixup control handling

gspca_mr97310a: cleanup/fixup control handling
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 58d0b2f6
...@@ -64,11 +64,9 @@ struct sd { ...@@ -64,11 +64,9 @@ struct sd {
u8 cam_type; /* 0 is CIF and 1 is VGA */ u8 cam_type; /* 0 is CIF and 1 is VGA */
u8 sensor_type; /* We use 0 and 1 here, too. */ u8 sensor_type; /* We use 0 and 1 here, too. */
u8 do_lcd_stop; u8 do_lcd_stop;
u8 regs[15];
int brightness; int brightness;
u16 exposure; u16 exposure;
u8 autogain;
u8 gain; u8 gain;
}; };
...@@ -85,10 +83,14 @@ static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); ...@@ -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_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
static int sd_setgain(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 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 */ /* V4L2 controls supported by the driver */
static struct ctrl sd_ctrls[] = { static struct ctrl sd_ctrls[] = {
{ {
#define BRIGHTNESS_IDX 0
{ {
.id = V4L2_CID_BRIGHTNESS, .id = V4L2_CID_BRIGHTNESS,
.type = V4L2_CTRL_TYPE_INTEGER, .type = V4L2_CTRL_TYPE_INTEGER,
...@@ -103,6 +105,7 @@ static struct ctrl sd_ctrls[] = { ...@@ -103,6 +105,7 @@ static struct ctrl sd_ctrls[] = {
.get = sd_getbrightness, .get = sd_getbrightness,
}, },
{ {
#define EXPOSURE_IDX 1
{ {
.id = V4L2_CID_EXPOSURE, .id = V4L2_CID_EXPOSURE,
.type = V4L2_CTRL_TYPE_INTEGER, .type = V4L2_CTRL_TYPE_INTEGER,
...@@ -117,6 +120,7 @@ static struct ctrl sd_ctrls[] = { ...@@ -117,6 +120,7 @@ static struct ctrl sd_ctrls[] = {
.get = sd_getexposure, .get = sd_getexposure,
}, },
{ {
#define GAIN_IDX 2
{ {
.id = V4L2_CID_GAIN, .id = V4L2_CID_GAIN,
.type = V4L2_CTRL_TYPE_INTEGER, .type = V4L2_CTRL_TYPE_INTEGER,
...@@ -360,14 +364,24 @@ static int sd_config(struct gspca_dev *gspca_dev, ...@@ -360,14 +364,24 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam = &gspca_dev->cam; cam = &gspca_dev->cam;
cam->cam_mode = vga_mode; cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode); cam->nmodes = ARRAY_SIZE(vga_mode);
sd->cam_type = CAM_TYPE_VGA;
PDEBUG(D_PROBE, PDEBUG(D_PROBE,
"MR97310A camera detected" "MR97310A camera detected"
" (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
if (id->idProduct == 0x010e) { if (id->idProduct == 0x010e) {
cam->nmodes--;
sd->cam_type = CAM_TYPE_CIF; 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; return 0;
} }
...@@ -377,35 +391,6 @@ static int sd_init(struct gspca_dev *gspca_dev) ...@@ -377,35 +391,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
return 0; 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) static int start_cif_cam(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
...@@ -452,6 +437,11 @@ static int start_cif_cam(struct gspca_dev *gspca_dev) ...@@ -452,6 +437,11 @@ static int start_cif_cam(struct gspca_dev *gspca_dev)
sd->sensor_type = 1; sd->sensor_type = 1;
PDEBUG(D_ERR, "Sensor type is %01x", sd->sensor_type); 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); memcpy(data, startup_string, 11);
if (sd->sensor_type) if (sd->sensor_type)
data[5] = 0xbb; data[5] = 0xbb;
...@@ -504,18 +494,15 @@ static int start_cif_cam(struct gspca_dev *gspca_dev) ...@@ -504,18 +494,15 @@ static int start_cif_cam(struct gspca_dev *gspca_dev)
ARRAY_SIZE(cif_sensor0_init_data)); ARRAY_SIZE(cif_sensor0_init_data));
} else { /* sd->sensor_type = 1 */ } else { /* sd->sensor_type = 1 */
const struct sensor_w_data cif_sensor1_init_data[] = { const struct sensor_w_data cif_sensor1_init_data[] = {
/* Reg 3,4, 7,8 get set by the controls */
{0x02, 0x00, {0x10}, 1}, {0x02, 0x00, {0x10}, 1},
{0x03, 0x01, {0x12}, 1}, {0x05, 0x01, {0x22}, 1}, /* 5/6 also seen as 65h/32h */
{0x04, 0x01, {0x05}, 1}, {0x06, 0x01, {0x00}, 1},
{0x05, 0x01, {0x65}, 1},
{0x06, 0x01, {0x32}, 1},
{0x07, 0x01, {0x00}, 1},
{0x08, 0x02, {0x06}, 1},
{0x09, 0x02, {0x0e}, 1}, {0x09, 0x02, {0x0e}, 1},
{0x0a, 0x02, {0x05}, 1}, {0x0a, 0x02, {0x05}, 1},
{0x0b, 0x02, {0x05}, 1}, {0x0b, 0x02, {0x05}, 1},
{0x0c, 0x02, {0x0f}, 1}, {0x0c, 0x02, {0x0f}, 1},
{0x0d, 0x02, {0x00}, 1}, {0x0d, 0x02, {0x07}, 1},
{0x0e, 0x02, {0x0c}, 1}, {0x0e, 0x02, {0x0c}, 1},
{0x0f, 0x00, {0x00}, 1}, {0x0f, 0x00, {0x00}, 1},
{0x10, 0x00, {0x06}, 1}, {0x10, 0x00, {0x06}, 1},
...@@ -530,19 +517,18 @@ static int start_cif_cam(struct gspca_dev *gspca_dev) ...@@ -530,19 +517,18 @@ static int start_cif_cam(struct gspca_dev *gspca_dev)
if (err_code < 0) if (err_code < 0)
return err_code; return err_code;
setbrightness(gspca_dev);
setexposure(gspca_dev);
setgain(gspca_dev);
msleep(200); msleep(200);
data[0] = 0x00; data[0] = 0x00;
data[1] = 0x4d; /* ISOC transfering enable... */ data[1] = 0x4d; /* ISOC transfering enable... */
err_code = mr_write(gspca_dev, 2); err_code = mr_write(gspca_dev, 2);
if (err_code < 0) if (err_code < 0)
return err_code; return err_code;
msleep(200);
err_code = adjust_cif_sensor(gspca_dev);
if (err_code < 0)
return err_code;
msleep(200);
return 0; return 0;
} }
...@@ -711,11 +697,6 @@ static int sd_start(struct gspca_dev *gspca_dev) ...@@ -711,11 +697,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
int err_code; int err_code;
struct cam *cam; 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; cam = &gspca_dev->cam;
sd->sof_read = 0; sd->sof_read = 0;
/* /*
...@@ -760,11 +741,16 @@ static void setbrightness(struct gspca_dev *gspca_dev) ...@@ -760,11 +741,16 @@ static void setbrightness(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
u8 val; 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) { if (sd->brightness > 0) {
sensor_write1(gspca_dev, 7, 0); sensor_write1(gspca_dev, 7, 0x00);
val = sd->brightness; val = sd->brightness;
} else { } else {
sensor_write1(gspca_dev, 7, 1); sensor_write1(gspca_dev, 7, 0x01);
val = 257 - sd->brightness; val = 257 - sd->brightness;
} }
sensor_write1(gspca_dev, 8, val); sensor_write1(gspca_dev, 8, val);
...@@ -775,6 +761,9 @@ static void setexposure(struct gspca_dev *gspca_dev) ...@@ -775,6 +761,9 @@ static void setexposure(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
u8 val; u8 val;
if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX))
return;
val = sd->exposure >> 4; val = sd->exposure >> 4;
sensor_write1(gspca_dev, 3, val); sensor_write1(gspca_dev, 3, val);
val = sd->exposure & 0xf; val = sd->exposure & 0xf;
...@@ -785,6 +774,9 @@ static void setgain(struct gspca_dev *gspca_dev) ...@@ -785,6 +774,9 @@ static void setgain(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) 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); sensor_write1(gspca_dev, 3, sd->gain);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment