From 29da71214c388ee2636e73adecb0d781d6f294c8 Mon Sep 17 00:00:00 2001 From: Erik Andr?n Date: Sun, 4 Jan 2009 20:52:48 +0100 Subject: gspca - m5602-mt9m111: Convert the mt9m111 to use a v4l2 ctrl cache From: Erik Andr?n Priority: normal Signed-off-by: Erik Andr?n --- .../media/video/gspca/m5602/m5602_mt9m111.c | 65 +++++++++++++--------- 1 file changed, 40 insertions(+), 25 deletions(-) (limited to 'linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c') diff --git a/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c index 7d3f9e348..43791a6b8 100644 --- a/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c +++ b/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c @@ -32,6 +32,7 @@ static struct v4l2_pix_format mt9m111_modes[] = { }; const static struct ctrl mt9m111_ctrls[] = { +#define VFLIP_IDX 0 { { .id = V4L2_CID_VFLIP, @@ -44,7 +45,9 @@ const static struct ctrl mt9m111_ctrls[] = { }, .set = mt9m111_set_vflip, .get = mt9m111_get_vflip - }, { + }, +#define HFLIP_IDX 1 + { { .id = V4L2_CID_HFLIP, .type = V4L2_CTRL_TYPE_BOOLEAN, @@ -56,7 +59,9 @@ const static struct ctrl mt9m111_ctrls[] = { }, .set = mt9m111_set_hflip, .get = mt9m111_get_hflip - }, { + }, +#define GAIN_IDX 2 + { { .id = V4L2_CID_GAIN, .type = V4L2_CTRL_TYPE_INTEGER, @@ -79,6 +84,7 @@ int mt9m111_probe(struct sd *sd) { u8 data[2] = {0x00, 0x00}; int i; + s32 *sensor_settings; if (force_sensor) { if (force_sensor == MT9M111_SENSOR) { @@ -117,10 +123,19 @@ int mt9m111_probe(struct sd *sd) return -ENODEV; sensor_found: + sensor_settings = kmalloc(ARRAY_SIZE(mt9m111_ctrls) * sizeof(s32), GFP_KERNEL); + if (!sensor_settings) + return -ENOMEM; + sd->gspca_dev.cam.cam_mode = mt9m111_modes; sd->gspca_dev.cam.nmodes = ARRAY_SIZE(mt9m111_modes); sd->desc->ctrls = mt9m111_ctrls; sd->desc->nctrls = ARRAY_SIZE(mt9m111_ctrls); + + for (i = 0; i < ARRAY_SIZE(mt9m111_ctrls); i++) + sensor_settings[i] = mt9m111_ctrls[i].qctrl.default_value; + sd->sensor_priv = sensor_settings; + return 0; } @@ -155,18 +170,21 @@ int mt9m111_power_down(struct sd *sd) return 0; } +void mt9m111_disconnect(struct sd *sd) +{ + sd->sensor = NULL; + kfree(sd->sensor_priv); +} + int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) { - int err; - u8 data[2] = {0x00, 0x00}; struct sd *sd = (struct sd *) gspca_dev; + s32 *sensor_settings = sd->sensor_priv; - err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, - data, 2); - *val = data[0] & MT9M111_RMB_MIRROR_ROWS; + *val = sensor_settings[VFLIP_IDX]; PDEBUG(D_V4L2, "Read vertical flip %d", *val); - return err; + return 0; } int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) @@ -174,9 +192,12 @@ int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) int err; u8 data[2] = {0x00, 0x00}; struct sd *sd = (struct sd *) gspca_dev; + s32 *sensor_settings = sd->sensor_priv; PDEBUG(D_V4L2, "Set vertical flip to %d", val); + sensor_settings[VFLIP_IDX] = val; + /* Set the correct page map */ err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); if (err < 0) @@ -194,16 +215,13 @@ int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) { - int err; - u8 data[2] = {0x00, 0x00}; struct sd *sd = (struct sd *) gspca_dev; + s32 *sensor_settings = sd->sensor_priv; - err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, - data, 2); - *val = data[0] & MT9M111_RMB_MIRROR_COLS; + *val = sensor_settings[HFLIP_IDX]; PDEBUG(D_V4L2, "Read horizontal flip %d", *val); - return err; + return 0; } int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) @@ -211,9 +229,11 @@ int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) int err; u8 data[2] = {0x00, 0x00}; struct sd *sd = (struct sd *) gspca_dev; + s32 *sensor_settings = sd->sensor_priv; PDEBUG(D_V4L2, "Set horizontal flip to %d", val); + sensor_settings[HFLIP_IDX] = val; /* Set the correct page map */ err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); if (err < 0) @@ -231,21 +251,13 @@ int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val) { - int err, tmp; - u8 data[2] = {0x00, 0x00}; struct sd *sd = (struct sd *) gspca_dev; + s32 *sensor_settings = sd->sensor_priv; - err = m5602_read_sensor(sd, MT9M111_SC_GLOBAL_GAIN, data, 2); - tmp = ((data[1] << 8) | data[0]); - - *val = ((tmp & (1 << 10)) * 2) | - ((tmp & (1 << 9)) * 2) | - ((tmp & (1 << 8)) * 2) | - (tmp & 0x7f); - + *val = sensor_settings[GAIN_IDX]; PDEBUG(D_V4L2, "Read gain %d", *val); - return err; + return 0; } int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) @@ -253,6 +265,9 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) int err, tmp; u8 data[2] = {0x00, 0x00}; struct sd *sd = (struct sd *) gspca_dev; + s32 *sensor_settings = sd->sensor_priv; + + sensor_settings[GAIN_IDX] = val; /* Set the correct page map */ err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); -- cgit v1.2.3 From 7c02d8dbb5d410ca9cc0af821a6d24a7f6412d86 Mon Sep 17 00:00:00 2001 From: Erik Andr?n Date: Tue, 6 Jan 2009 15:59:42 +0100 Subject: gspca - m5602-mt9m111: Remove the unused power_down struct member From: Erik Andr?n The power_down sensor struct member is almost has no purpose in the current driver abstraction. Remove it. Priority: normal Signed-off-by: Erik Andr?n --- linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c') diff --git a/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c index 43791a6b8..519548d07 100644 --- a/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c +++ b/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c @@ -165,11 +165,6 @@ int mt9m111_init(struct sd *sd) return (err < 0) ? err : 0; } -int mt9m111_power_down(struct sd *sd) -{ - return 0; -} - void mt9m111_disconnect(struct sd *sd) { sd->sensor = NULL; -- cgit v1.2.3 From 60879db1480a780ca0be9895ed266b5c812397fd Mon Sep 17 00:00:00 2001 From: Erik Andr?n Date: Thu, 8 Jan 2009 22:11:05 +0100 Subject: gspca - m5602-mt9m111: Set the cached v4l2 ctrl values From: Erik Andr?n When we resume the machine we want the previously set values, not the default values. Fix this for the mt9m111 sensor Priority: normal Signed-off-by: Erik Andr?n --- linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c') diff --git a/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c index 519548d07..8700f37de 100644 --- a/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c +++ b/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c @@ -136,12 +136,16 @@ sensor_found: sensor_settings[i] = mt9m111_ctrls[i].qctrl.default_value; sd->sensor_priv = sensor_settings; + if (dump_sensor) + mt9m111_dump_registers(sd); + return 0; } int mt9m111_init(struct sd *sd) { int i, err = 0; + s32 *sensor_settings = sd->sensor_priv; /* Init the sensor */ for (i = 0; i < ARRAY_SIZE(init_mt9m111) && !err; i++) { @@ -159,10 +163,17 @@ int mt9m111_init(struct sd *sd) } } - if (dump_sensor) - mt9m111_dump_registers(sd); + err = mt9m111_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]); + if (err < 0) + return err; + + err = mt9m111_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]); + if (err < 0) + return err; + + err = mt9m111_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); - return (err < 0) ? err : 0; + return err; } void mt9m111_disconnect(struct sd *sd) -- cgit v1.2.3 From d6a285a1117236b4293bc9a70baf0c967aabc54e Mon Sep 17 00:00:00 2001 From: Erik Andr?n Date: Fri, 3 Apr 2009 07:49:10 +0200 Subject: gspca - m5602: Let all ctrls on all sensors be static From: Erik Andr?n All hail the static keyword Priority: normal Signed-off-by: Erik Andr?n --- .../media/video/gspca/m5602/m5602_mt9m111.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c') diff --git a/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c index 8700f37de..8017782ef 100644 --- a/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c +++ b/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c @@ -18,6 +18,13 @@ #include "m5602_mt9m111.h" +static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val); +static int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); +static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); +static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val); +static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val); +static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val); + static struct v4l2_pix_format mt9m111_modes[] = { { 640, @@ -123,7 +130,8 @@ int mt9m111_probe(struct sd *sd) return -ENODEV; sensor_found: - sensor_settings = kmalloc(ARRAY_SIZE(mt9m111_ctrls) * sizeof(s32), GFP_KERNEL); + sensor_settings = kmalloc(ARRAY_SIZE(mt9m111_ctrls) * sizeof(s32), + GFP_KERNEL); if (!sensor_settings) return -ENOMEM; @@ -182,7 +190,7 @@ void mt9m111_disconnect(struct sd *sd) kfree(sd->sensor_priv); } -int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) +static int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; s32 *sensor_settings = sd->sensor_priv; @@ -193,7 +201,7 @@ int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) return 0; } -int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) +static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) { int err; u8 data[2] = {0x00, 0x00}; @@ -219,7 +227,7 @@ int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) return err; } -int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) +static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; s32 *sensor_settings = sd->sensor_priv; @@ -230,7 +238,7 @@ int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) return 0; } -int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) +static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) { int err; u8 data[2] = {0x00, 0x00}; @@ -255,7 +263,7 @@ int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) return err; } -int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val) +static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; s32 *sensor_settings = sd->sensor_priv; @@ -266,7 +274,7 @@ int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val) return 0; } -int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) +static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) { int err, tmp; u8 data[2] = {0x00, 0x00}; -- cgit v1.2.3 From 2c14a41e11fbda8426340a33e84b16aaad6bb892 Mon Sep 17 00:00:00 2001 From: Erik Andr?n Date: Fri, 9 Jan 2009 17:35:00 +0100 Subject: gspca - m5602: Move all dump_sensor to the init function From: Erik Andr?n Priority: normal Signed-off-by: Erik Andr?n --- linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c') diff --git a/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c index 8017782ef..8036619e7 100644 --- a/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c +++ b/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c @@ -144,9 +144,6 @@ sensor_found: sensor_settings[i] = mt9m111_ctrls[i].qctrl.default_value; sd->sensor_priv = sensor_settings; - if (dump_sensor) - mt9m111_dump_registers(sd); - return 0; } @@ -171,6 +168,9 @@ int mt9m111_init(struct sd *sd) } } + if (dump_sensor) + mt9m111_dump_registers(sd); + err = mt9m111_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]); if (err < 0) return err; -- cgit v1.2.3 From a694efccfe707bc3696b043791107fd779d38803 Mon Sep 17 00:00:00 2001 From: Erik Andr?n Date: Fri, 9 Jan 2009 17:53:20 +0100 Subject: gspca - m5602-mt9m111: More redundant init cleanup From: Erik Andr?n Priority: normal Signed-off-by: Erik Andr?n --- linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c | 1 - 1 file changed, 1 deletion(-) (limited to 'linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c') diff --git a/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c index 8036619e7..a057b8d5d 100644 --- a/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c +++ b/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c @@ -84,7 +84,6 @@ const static struct ctrl mt9m111_ctrls[] = { } }; - static void mt9m111_dump_registers(struct sd *sd); int mt9m111_probe(struct sd *sd) -- cgit v1.2.3 From 4874985087f6574aa443ab801e631ee86f03966f Mon Sep 17 00:00:00 2001 From: Erik Andr?n Date: Fri, 9 Jan 2009 18:03:27 +0100 Subject: gspca - m5602-mt9m111: Implement an auto white balancing control From: Erik Andr?n Priority: normal Signed-off-by: Erik Andr?n --- .../media/video/gspca/m5602/m5602_mt9m111.c | 50 ++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c') diff --git a/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c index a057b8d5d..37a7fc82a 100644 --- a/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c +++ b/linux/drivers/media/video/gspca/m5602/m5602_mt9m111.c @@ -24,6 +24,11 @@ static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val); static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val); static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val); +static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev, + __s32 val); +static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev, + __s32 *val); + static struct v4l2_pix_format mt9m111_modes[] = { { @@ -81,6 +86,20 @@ const static struct ctrl mt9m111_ctrls[] = { }, .set = mt9m111_set_gain, .get = mt9m111_get_gain + }, +#define AUTO_WHITE_BALANCE_IDX 3 + { + { + .id = V4L2_CID_AUTO_WHITE_BALANCE, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "auto white balance", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + .set = mt9m111_set_auto_white_balance, + .get = mt9m111_get_auto_white_balance } }; @@ -273,6 +292,37 @@ static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val) return 0; } +static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev, + __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + s32 *sensor_settings = sd->sensor_priv; + int err; + u8 data[2]; + + err = m5602_read_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2); + if (err < 0) + return err; + + sensor_settings[AUTO_WHITE_BALANCE_IDX] = val & 0x01; + data[0] = ((data[0] & 0xfd) | ((val & 0x01) << 1)); + + err = m5602_write_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2); + + PDEBUG(D_V4L2, "Set auto white balance %d", val); + return err; +} + +static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev, + __s32 *val) { + struct sd *sd = (struct sd *) gspca_dev; + s32 *sensor_settings = sd->sensor_priv; + + *val = sensor_settings[AUTO_WHITE_BALANCE_IDX]; + PDEBUG(D_V4L2, "Read auto white balance %d", *val); + return 0; +} + static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) { int err, tmp; -- cgit v1.2.3