diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c index 3a3df102637f..4ecba9b2a5a4 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c +++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c @@ -26,6 +26,8 @@ static int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); static int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val); static int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val); static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val); +static int s5k4aa_get_noise(struct gspca_dev *gspca_dev, __s32 *val); +static int s5k4aa_set_noise(struct gspca_dev *gspca_dev, __s32 val); static const @@ -131,7 +133,21 @@ const static struct ctrl s5k4aa_ctrls[] = { }, .set = s5k4aa_set_exposure, .get = s5k4aa_get_exposure - } + }, +#define NOISE_SUPP_IDX 4 + { + { + .id = V4L2_CID_PRIVATE_BASE, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Noise suppression (smoothing)", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + .set = s5k4aa_set_noise, + .get = s5k4aa_get_noise + }, }; static void s5k4aa_dump_registers(struct sd *sd); @@ -304,13 +320,15 @@ int s5k4aa_init(struct sd *sd) if (err < 0) return err; + err = s5k4aa_set_noise(&sd->gspca_dev, sensor_settings[NOISE_SUPP_IDX]); + if (err < 0) + return err; + err = s5k4aa_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]); if (err < 0) return err; - err = s5k4aa_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]); - - return err; + return s5k4aa_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]); } static int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) @@ -495,6 +513,34 @@ static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val) return err; } +static int s5k4aa_get_noise(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + s32 *sensor_settings = sd->sensor_priv; + + *val = sensor_settings[NOISE_SUPP_IDX]; + PDEBUG(D_V4L2, "Read noise %d", *val); + return 0; +} + +static int s5k4aa_set_noise(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + s32 *sensor_settings = sd->sensor_priv; + u8 data = S5K4AA_PAGE_MAP_2; + int err; + + sensor_settings[NOISE_SUPP_IDX] = val; + + PDEBUG(D_V4L2, "Set noise to %d", val); + err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1); + if (err < 0) + return err; + + data = val & 0x01; + return m5602_write_sensor(sd, S5K4AA_NOISE_SUPP, &data, 1); +} + void s5k4aa_disconnect(struct sd *sd) { sd->sensor = NULL; diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h index fbcb9c1e8c9d..8299f216c20d 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h +++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h @@ -49,6 +49,7 @@ #define S5K4AA_EXPOSURE_LO 0x18 #define S5K4AA_GAIN_1 0x1f /* (digital?) gain : 5 bits */ #define S5K4AA_GAIN_2 0x20 /* (analogue?) gain : 7 bits */ +#define S5K4AA_NOISE_SUPP 0x37 #define S5K4AA_RM_ROW_SKIP_4X 0x08 #define S5K4AA_RM_ROW_SKIP_2X 0x04 diff --git a/drivers/media/video/gspca/m5602/m5602_sensor.h b/drivers/media/video/gspca/m5602/m5602_sensor.h index 5b76b6b62152..c3a72117b39c 100644 --- a/drivers/media/video/gspca/m5602/m5602_sensor.h +++ b/drivers/media/video/gspca/m5602/m5602_sensor.h @@ -22,6 +22,7 @@ #include "m5602_bridge.h" #define M5602_V4L2_CID_GREEN_BALANCE (V4L2_CID_PRIVATE_BASE + 0) +#define M5602_V4L2_CID_NOISE_SUPPRESION (V4L2_CID_PRIVATE_BASE + 1) /* Enumerates all supported sensors */ enum sensors {