Loading drivers/media/video/gspca/cpia1.c +127 −358 Original line number Diff line number Diff line Loading @@ -225,6 +225,15 @@ MODULE_LICENSE("GPL"); #define FIRMWARE_VERSION(x, y) (sd->params.version.firmwareVersion == (x) && \ sd->params.version.firmwareRevision == (y)) #define CPIA1_CID_COMP_TARGET (V4L2_CTRL_CLASS_USER + 0x1000) #define BRIGHTNESS_DEF 50 #define CONTRAST_DEF 48 #define SATURATION_DEF 50 #define FREQ_DEF V4L2_CID_POWER_LINE_FREQUENCY_50HZ #define ILLUMINATORS_1_DEF 0 #define ILLUMINATORS_2_DEF 0 #define COMP_TARGET_DEF CPIA_COMPRESSION_TARGET_QUALITY /* Developer's Guide Table 5 p 3-34 * indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/ static u8 flicker_jumps[2][2][4] = Loading Loading @@ -360,135 +369,9 @@ struct sd { atomic_t fps; int exposure_count; u8 exposure_status; struct v4l2_ctrl *freq; u8 mainsFreq; /* 0 = 50hz, 1 = 60hz */ u8 first_frame; u8 freq; }; /* V4L2 controls supported by the driver */ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val); static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setcomptarget(struct gspca_dev *gspca_dev, __s32 val); static int sd_getcomptarget(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setilluminator1(struct gspca_dev *gspca_dev, __s32 val); static int sd_getilluminator1(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setilluminator2(struct gspca_dev *gspca_dev, __s32 val); static int sd_getilluminator2(struct gspca_dev *gspca_dev, __s32 *val); static const struct ctrl sd_ctrls[] = { { #define BRIGHTNESS_IDX 0 { .id = V4L2_CID_BRIGHTNESS, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Brightness", .minimum = 0, .maximum = 100, .step = 1, #define BRIGHTNESS_DEF 50 .default_value = BRIGHTNESS_DEF, .flags = 0, }, .set = sd_setbrightness, .get = sd_getbrightness, }, #define CONTRAST_IDX 1 { { .id = V4L2_CID_CONTRAST, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Contrast", .minimum = 0, .maximum = 96, .step = 8, #define CONTRAST_DEF 48 .default_value = CONTRAST_DEF, }, .set = sd_setcontrast, .get = sd_getcontrast, }, #define SATURATION_IDX 2 { { .id = V4L2_CID_SATURATION, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Saturation", .minimum = 0, .maximum = 100, .step = 1, #define SATURATION_DEF 50 .default_value = SATURATION_DEF, }, .set = sd_setsaturation, .get = sd_getsaturation, }, #define POWER_LINE_FREQUENCY_IDX 3 { { .id = V4L2_CID_POWER_LINE_FREQUENCY, .type = V4L2_CTRL_TYPE_MENU, .name = "Light frequency filter", .minimum = 0, .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ .step = 1, #define FREQ_DEF 1 .default_value = FREQ_DEF, }, .set = sd_setfreq, .get = sd_getfreq, }, #define ILLUMINATORS_1_IDX 4 { { .id = V4L2_CID_ILLUMINATORS_1, .type = V4L2_CTRL_TYPE_BOOLEAN, .name = "Illuminator 1", .minimum = 0, .maximum = 1, .step = 1, #define ILLUMINATORS_1_DEF 0 .default_value = ILLUMINATORS_1_DEF, }, .set = sd_setilluminator1, .get = sd_getilluminator1, }, #define ILLUMINATORS_2_IDX 5 { { .id = V4L2_CID_ILLUMINATORS_2, .type = V4L2_CTRL_TYPE_BOOLEAN, .name = "Illuminator 2", .minimum = 0, .maximum = 1, .step = 1, #define ILLUMINATORS_2_DEF 0 .default_value = ILLUMINATORS_2_DEF, }, .set = sd_setilluminator2, .get = sd_getilluminator2, }, #define COMP_TARGET_IDX 6 { { #define V4L2_CID_COMP_TARGET V4L2_CID_PRIVATE_BASE .id = V4L2_CID_COMP_TARGET, .type = V4L2_CTRL_TYPE_MENU, .name = "Compression Target", .minimum = 0, .maximum = 1, .step = 1, #define COMP_TARGET_DEF CPIA_COMPRESSION_TARGET_QUALITY .default_value = COMP_TARGET_DEF, }, .set = sd_setcomptarget, .get = sd_getcomptarget, }, }; static const struct v4l2_pix_format mode[] = { Loading Loading @@ -770,15 +653,6 @@ static void reset_camera_params(struct gspca_dev *gspca_dev) params->apcor.gain2 = 0x16; params->apcor.gain4 = 0x24; params->apcor.gain8 = 0x34; params->flickerControl.flickerMode = 0; params->flickerControl.disabled = 1; params->flickerControl.coarseJump = flicker_jumps[sd->mainsFreq] [params->sensorFps.baserate] [params->sensorFps.divisor]; params->flickerControl.allowableOverExposure = find_over_exposure(params->colourParams.brightness); params->vlOffset.gain1 = 20; params->vlOffset.gain2 = 24; params->vlOffset.gain4 = 26; Loading @@ -798,6 +672,15 @@ static void reset_camera_params(struct gspca_dev *gspca_dev) params->sensorFps.divisor = 1; params->sensorFps.baserate = 1; params->flickerControl.flickerMode = 0; params->flickerControl.disabled = 1; params->flickerControl.coarseJump = flicker_jumps[sd->mainsFreq] [params->sensorFps.baserate] [params->sensorFps.divisor]; params->flickerControl.allowableOverExposure = find_over_exposure(params->colourParams.brightness); params->yuvThreshold.yThreshold = 6; /* From windows driver */ params->yuvThreshold.uvThreshold = 6; /* From windows driver */ Loading Loading @@ -1110,9 +993,6 @@ static int command_setlights(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; int ret, p1, p2; if (!sd->params.qx3.qx3_detected) return 0; p1 = (sd->params.qx3.bottomlight == 0) << 1; p2 = (sd->params.qx3.toplight == 0) << 3; Loading Loading @@ -1551,8 +1431,10 @@ static void restart_flicker(struct gspca_dev *gspca_dev) static int sd_config(struct gspca_dev *gspca_dev, const struct usb_device_id *id) { struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; sd->mainsFreq = FREQ_DEF == V4L2_CID_POWER_LINE_FREQUENCY_60HZ; reset_camera_params(gspca_dev); PDEBUG(D_PROBE, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)", Loading @@ -1562,8 +1444,25 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->cam_mode = mode; cam->nmodes = ARRAY_SIZE(mode); sd_setfreq(gspca_dev, FREQ_DEF); goto_low_power(gspca_dev); /* Check the firmware version. */ sd->params.version.firmwareVersion = 0; get_version_information(gspca_dev); if (sd->params.version.firmwareVersion != 1) { PDEBUG(D_ERR, "only firmware version 1 is supported (got: %d)", sd->params.version.firmwareVersion); return -ENODEV; } /* A bug in firmware 1-02 limits gainMode to 2 */ if (sd->params.version.firmwareRevision <= 2 && sd->params.exposure.gainMode > 2) { sd->params.exposure.gainMode = 2; } /* set QX3 detected flag */ sd->params.qx3.qx3_detected = (sd->params.pnpID.vendor == 0x0813 && sd->params.pnpID.product == 0x0001); return 0; } Loading Loading @@ -1602,21 +1501,6 @@ static int sd_start(struct gspca_dev *gspca_dev) /* Check the firmware version. */ sd->params.version.firmwareVersion = 0; get_version_information(gspca_dev); if (sd->params.version.firmwareVersion != 1) { PDEBUG(D_ERR, "only firmware version 1 is supported (got: %d)", sd->params.version.firmwareVersion); return -ENODEV; } /* A bug in firmware 1-02 limits gainMode to 2 */ if (sd->params.version.firmwareRevision <= 2 && sd->params.exposure.gainMode > 2) { sd->params.exposure.gainMode = 2; } /* set QX3 detected flag */ sd->params.qx3.qx3_detected = (sd->params.pnpID.vendor == 0x0813 && sd->params.pnpID.product == 0x0001); /* The fatal error checking should be done after * the camera powers up (developer's guide p 3-38) */ Loading Loading @@ -1785,9 +1669,6 @@ static int sd_init(struct gspca_dev *gspca_dev) or disable the illuminator controls, if this isn't a QX3 */ if (sd->params.qx3.qx3_detected) command_setlights(gspca_dev); else gspca_dev->ctrl_dis |= ((1 << ILLUMINATORS_1_IDX) | (1 << ILLUMINATORS_2_IDX)); sd_stopN(gspca_dev); Loading Loading @@ -1871,235 +1752,123 @@ static void sd_dq_callback(struct gspca_dev *gspca_dev) do_command(gspca_dev, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0); } static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) static int sd_s_ctrl(struct v4l2_ctrl *ctrl) { struct gspca_dev *gspca_dev = container_of(ctrl->handler, struct gspca_dev, ctrl_handler); struct sd *sd = (struct sd *)gspca_dev; int ret; sd->params.colourParams.brightness = val; sd->params.flickerControl.allowableOverExposure = find_over_exposure(sd->params.colourParams.brightness); if (gspca_dev->streaming) { ret = command_setcolourparams(gspca_dev); if (ret) return ret; return command_setflickerctrl(gspca_dev); } return 0; } static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; gspca_dev->usb_err = 0; *val = sd->params.colourParams.brightness; if (!gspca_dev->streaming && ctrl->id != V4L2_CID_POWER_LINE_FREQUENCY) return 0; } static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; sd->params.colourParams.contrast = val; if (gspca_dev->streaming) return command_setcolourparams(gspca_dev); return 0; } static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; *val = sd->params.colourParams.contrast; return 0; } static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; sd->params.colourParams.saturation = val; if (gspca_dev->streaming) return command_setcolourparams(gspca_dev); return 0; } static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; *val = sd->params.colourParams.saturation; return 0; } static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; int on; switch (val) { case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ on = 0; switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: sd->params.colourParams.brightness = ctrl->val; sd->params.flickerControl.allowableOverExposure = find_over_exposure(sd->params.colourParams.brightness); gspca_dev->usb_err = command_setcolourparams(gspca_dev); if (!gspca_dev->usb_err) gspca_dev->usb_err = command_setflickerctrl(gspca_dev); break; case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ on = 1; sd->mainsFreq = 0; case V4L2_CID_CONTRAST: sd->params.colourParams.contrast = ctrl->val; gspca_dev->usb_err = command_setcolourparams(gspca_dev); break; case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ on = 1; sd->mainsFreq = 1; case V4L2_CID_SATURATION: sd->params.colourParams.saturation = ctrl->val; gspca_dev->usb_err = command_setcolourparams(gspca_dev); break; default: return -EINVAL; } sd->freq = val; case V4L2_CID_POWER_LINE_FREQUENCY: sd->mainsFreq = ctrl->val == V4L2_CID_POWER_LINE_FREQUENCY_60HZ; sd->params.flickerControl.coarseJump = flicker_jumps[sd->mainsFreq] [sd->params.sensorFps.baserate] [sd->params.sensorFps.divisor]; return set_flicker(gspca_dev, on, gspca_dev->streaming); } static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; *val = sd->freq; return 0; } static int sd_setcomptarget(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; sd->params.compressionTarget.frTargeting = val; if (gspca_dev->streaming) return command_setcompressiontarget(gspca_dev); return 0; } static int sd_getcomptarget(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; *val = sd->params.compressionTarget.frTargeting; return 0; } static int sd_setilluminator(struct gspca_dev *gspca_dev, __s32 val, int n) { struct sd *sd = (struct sd *) gspca_dev; int ret; if (!sd->params.qx3.qx3_detected) return -EINVAL; switch (n) { case 1: sd->params.qx3.bottomlight = val ? 1 : 0; gspca_dev->usb_err = set_flicker(gspca_dev, ctrl->val != V4L2_CID_POWER_LINE_FREQUENCY_DISABLED, gspca_dev->streaming); break; case 2: sd->params.qx3.toplight = val ? 1 : 0; case V4L2_CID_ILLUMINATORS_1: sd->params.qx3.bottomlight = ctrl->val; gspca_dev->usb_err = command_setlights(gspca_dev); break; default: return -EINVAL; } ret = command_setlights(gspca_dev); if (ret && ret != -EINVAL) ret = -EBUSY; return ret; } static int sd_setilluminator1(struct gspca_dev *gspca_dev, __s32 val) { return sd_setilluminator(gspca_dev, val, 1); } static int sd_setilluminator2(struct gspca_dev *gspca_dev, __s32 val) { return sd_setilluminator(gspca_dev, val, 2); } static int sd_getilluminator(struct gspca_dev *gspca_dev, __s32 *val, int n) { struct sd *sd = (struct sd *) gspca_dev; if (!sd->params.qx3.qx3_detected) return -EINVAL; switch (n) { case 1: *val = sd->params.qx3.bottomlight; case V4L2_CID_ILLUMINATORS_2: sd->params.qx3.toplight = ctrl->val; gspca_dev->usb_err = command_setlights(gspca_dev); break; case 2: *val = sd->params.qx3.toplight; case CPIA1_CID_COMP_TARGET: sd->params.compressionTarget.frTargeting = ctrl->val; gspca_dev->usb_err = command_setcompressiontarget(gspca_dev); break; default: return -EINVAL; } return 0; return gspca_dev->usb_err; } static int sd_getilluminator1(struct gspca_dev *gspca_dev, __s32 *val) { return sd_getilluminator(gspca_dev, val, 1); } static const struct v4l2_ctrl_ops sd_ctrl_ops = { .s_ctrl = sd_s_ctrl, }; static int sd_getilluminator2(struct gspca_dev *gspca_dev, __s32 *val) static int sd_init_controls(struct gspca_dev *gspca_dev) { return sd_getilluminator(gspca_dev, val, 2); } struct sd *sd = (struct sd *)gspca_dev; struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; static const char * const comp_target_menu[] = { "Quality", "Framerate", NULL }; static const struct v4l2_ctrl_config comp_target = { .ops = &sd_ctrl_ops, .id = CPIA1_CID_COMP_TARGET, .type = V4L2_CTRL_TYPE_MENU, .name = "Compression Target", .qmenu = comp_target_menu, .max = 1, .def = COMP_TARGET_DEF, }; static int sd_querymenu(struct gspca_dev *gspca_dev, struct v4l2_querymenu *menu) { switch (menu->id) { case V4L2_CID_POWER_LINE_FREQUENCY: switch (menu->index) { case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ strcpy((char *) menu->name, "NoFliker"); return 0; case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ strcpy((char *) menu->name, "50 Hz"); return 0; case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ strcpy((char *) menu->name, "60 Hz"); return 0; gspca_dev->vdev.ctrl_handler = hdl; v4l2_ctrl_handler_init(hdl, 7); v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_BRIGHTNESS, 0, 100, 1, BRIGHTNESS_DEF); v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_CONTRAST, 0, 96, 8, CONTRAST_DEF); v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_SATURATION, 0, 100, 1, SATURATION_DEF); sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, V4L2_CID_POWER_LINE_FREQUENCY, V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, FREQ_DEF); if (sd->params.qx3.qx3_detected) { v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_ILLUMINATORS_1, 0, 1, 1, ILLUMINATORS_1_DEF); v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_ILLUMINATORS_2, 0, 1, 1, ILLUMINATORS_2_DEF); } v4l2_ctrl_new_custom(hdl, &comp_target, NULL); if (hdl->error) { pr_err("Could not initialize controls\n"); return hdl->error; } break; case V4L2_CID_COMP_TARGET: switch (menu->index) { case CPIA_COMPRESSION_TARGET_QUALITY: strcpy((char *) menu->name, "Quality"); return 0; case CPIA_COMPRESSION_TARGET_FRAMERATE: strcpy((char *) menu->name, "Framerate"); return 0; } break; } return -EINVAL; } /* sub-driver description */ static const struct sd_desc sd_desc = { .name = MODULE_NAME, .ctrls = sd_ctrls, .nctrls = ARRAY_SIZE(sd_ctrls), .config = sd_config, .init = sd_init, .init_controls = sd_init_controls, .start = sd_start, .stopN = sd_stopN, .dq_callback = sd_dq_callback, .pkt_scan = sd_pkt_scan, .querymenu = sd_querymenu, #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) .other_input = 1, #endif Loading Loading
drivers/media/video/gspca/cpia1.c +127 −358 Original line number Diff line number Diff line Loading @@ -225,6 +225,15 @@ MODULE_LICENSE("GPL"); #define FIRMWARE_VERSION(x, y) (sd->params.version.firmwareVersion == (x) && \ sd->params.version.firmwareRevision == (y)) #define CPIA1_CID_COMP_TARGET (V4L2_CTRL_CLASS_USER + 0x1000) #define BRIGHTNESS_DEF 50 #define CONTRAST_DEF 48 #define SATURATION_DEF 50 #define FREQ_DEF V4L2_CID_POWER_LINE_FREQUENCY_50HZ #define ILLUMINATORS_1_DEF 0 #define ILLUMINATORS_2_DEF 0 #define COMP_TARGET_DEF CPIA_COMPRESSION_TARGET_QUALITY /* Developer's Guide Table 5 p 3-34 * indexed by [mains][sensorFps.baserate][sensorFps.divisor]*/ static u8 flicker_jumps[2][2][4] = Loading Loading @@ -360,135 +369,9 @@ struct sd { atomic_t fps; int exposure_count; u8 exposure_status; struct v4l2_ctrl *freq; u8 mainsFreq; /* 0 = 50hz, 1 = 60hz */ u8 first_frame; u8 freq; }; /* V4L2 controls supported by the driver */ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val); static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setcomptarget(struct gspca_dev *gspca_dev, __s32 val); static int sd_getcomptarget(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setilluminator1(struct gspca_dev *gspca_dev, __s32 val); static int sd_getilluminator1(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setilluminator2(struct gspca_dev *gspca_dev, __s32 val); static int sd_getilluminator2(struct gspca_dev *gspca_dev, __s32 *val); static const struct ctrl sd_ctrls[] = { { #define BRIGHTNESS_IDX 0 { .id = V4L2_CID_BRIGHTNESS, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Brightness", .minimum = 0, .maximum = 100, .step = 1, #define BRIGHTNESS_DEF 50 .default_value = BRIGHTNESS_DEF, .flags = 0, }, .set = sd_setbrightness, .get = sd_getbrightness, }, #define CONTRAST_IDX 1 { { .id = V4L2_CID_CONTRAST, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Contrast", .minimum = 0, .maximum = 96, .step = 8, #define CONTRAST_DEF 48 .default_value = CONTRAST_DEF, }, .set = sd_setcontrast, .get = sd_getcontrast, }, #define SATURATION_IDX 2 { { .id = V4L2_CID_SATURATION, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Saturation", .minimum = 0, .maximum = 100, .step = 1, #define SATURATION_DEF 50 .default_value = SATURATION_DEF, }, .set = sd_setsaturation, .get = sd_getsaturation, }, #define POWER_LINE_FREQUENCY_IDX 3 { { .id = V4L2_CID_POWER_LINE_FREQUENCY, .type = V4L2_CTRL_TYPE_MENU, .name = "Light frequency filter", .minimum = 0, .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ .step = 1, #define FREQ_DEF 1 .default_value = FREQ_DEF, }, .set = sd_setfreq, .get = sd_getfreq, }, #define ILLUMINATORS_1_IDX 4 { { .id = V4L2_CID_ILLUMINATORS_1, .type = V4L2_CTRL_TYPE_BOOLEAN, .name = "Illuminator 1", .minimum = 0, .maximum = 1, .step = 1, #define ILLUMINATORS_1_DEF 0 .default_value = ILLUMINATORS_1_DEF, }, .set = sd_setilluminator1, .get = sd_getilluminator1, }, #define ILLUMINATORS_2_IDX 5 { { .id = V4L2_CID_ILLUMINATORS_2, .type = V4L2_CTRL_TYPE_BOOLEAN, .name = "Illuminator 2", .minimum = 0, .maximum = 1, .step = 1, #define ILLUMINATORS_2_DEF 0 .default_value = ILLUMINATORS_2_DEF, }, .set = sd_setilluminator2, .get = sd_getilluminator2, }, #define COMP_TARGET_IDX 6 { { #define V4L2_CID_COMP_TARGET V4L2_CID_PRIVATE_BASE .id = V4L2_CID_COMP_TARGET, .type = V4L2_CTRL_TYPE_MENU, .name = "Compression Target", .minimum = 0, .maximum = 1, .step = 1, #define COMP_TARGET_DEF CPIA_COMPRESSION_TARGET_QUALITY .default_value = COMP_TARGET_DEF, }, .set = sd_setcomptarget, .get = sd_getcomptarget, }, }; static const struct v4l2_pix_format mode[] = { Loading Loading @@ -770,15 +653,6 @@ static void reset_camera_params(struct gspca_dev *gspca_dev) params->apcor.gain2 = 0x16; params->apcor.gain4 = 0x24; params->apcor.gain8 = 0x34; params->flickerControl.flickerMode = 0; params->flickerControl.disabled = 1; params->flickerControl.coarseJump = flicker_jumps[sd->mainsFreq] [params->sensorFps.baserate] [params->sensorFps.divisor]; params->flickerControl.allowableOverExposure = find_over_exposure(params->colourParams.brightness); params->vlOffset.gain1 = 20; params->vlOffset.gain2 = 24; params->vlOffset.gain4 = 26; Loading @@ -798,6 +672,15 @@ static void reset_camera_params(struct gspca_dev *gspca_dev) params->sensorFps.divisor = 1; params->sensorFps.baserate = 1; params->flickerControl.flickerMode = 0; params->flickerControl.disabled = 1; params->flickerControl.coarseJump = flicker_jumps[sd->mainsFreq] [params->sensorFps.baserate] [params->sensorFps.divisor]; params->flickerControl.allowableOverExposure = find_over_exposure(params->colourParams.brightness); params->yuvThreshold.yThreshold = 6; /* From windows driver */ params->yuvThreshold.uvThreshold = 6; /* From windows driver */ Loading Loading @@ -1110,9 +993,6 @@ static int command_setlights(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; int ret, p1, p2; if (!sd->params.qx3.qx3_detected) return 0; p1 = (sd->params.qx3.bottomlight == 0) << 1; p2 = (sd->params.qx3.toplight == 0) << 3; Loading Loading @@ -1551,8 +1431,10 @@ static void restart_flicker(struct gspca_dev *gspca_dev) static int sd_config(struct gspca_dev *gspca_dev, const struct usb_device_id *id) { struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; sd->mainsFreq = FREQ_DEF == V4L2_CID_POWER_LINE_FREQUENCY_60HZ; reset_camera_params(gspca_dev); PDEBUG(D_PROBE, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)", Loading @@ -1562,8 +1444,25 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->cam_mode = mode; cam->nmodes = ARRAY_SIZE(mode); sd_setfreq(gspca_dev, FREQ_DEF); goto_low_power(gspca_dev); /* Check the firmware version. */ sd->params.version.firmwareVersion = 0; get_version_information(gspca_dev); if (sd->params.version.firmwareVersion != 1) { PDEBUG(D_ERR, "only firmware version 1 is supported (got: %d)", sd->params.version.firmwareVersion); return -ENODEV; } /* A bug in firmware 1-02 limits gainMode to 2 */ if (sd->params.version.firmwareRevision <= 2 && sd->params.exposure.gainMode > 2) { sd->params.exposure.gainMode = 2; } /* set QX3 detected flag */ sd->params.qx3.qx3_detected = (sd->params.pnpID.vendor == 0x0813 && sd->params.pnpID.product == 0x0001); return 0; } Loading Loading @@ -1602,21 +1501,6 @@ static int sd_start(struct gspca_dev *gspca_dev) /* Check the firmware version. */ sd->params.version.firmwareVersion = 0; get_version_information(gspca_dev); if (sd->params.version.firmwareVersion != 1) { PDEBUG(D_ERR, "only firmware version 1 is supported (got: %d)", sd->params.version.firmwareVersion); return -ENODEV; } /* A bug in firmware 1-02 limits gainMode to 2 */ if (sd->params.version.firmwareRevision <= 2 && sd->params.exposure.gainMode > 2) { sd->params.exposure.gainMode = 2; } /* set QX3 detected flag */ sd->params.qx3.qx3_detected = (sd->params.pnpID.vendor == 0x0813 && sd->params.pnpID.product == 0x0001); /* The fatal error checking should be done after * the camera powers up (developer's guide p 3-38) */ Loading Loading @@ -1785,9 +1669,6 @@ static int sd_init(struct gspca_dev *gspca_dev) or disable the illuminator controls, if this isn't a QX3 */ if (sd->params.qx3.qx3_detected) command_setlights(gspca_dev); else gspca_dev->ctrl_dis |= ((1 << ILLUMINATORS_1_IDX) | (1 << ILLUMINATORS_2_IDX)); sd_stopN(gspca_dev); Loading Loading @@ -1871,235 +1752,123 @@ static void sd_dq_callback(struct gspca_dev *gspca_dev) do_command(gspca_dev, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0); } static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) static int sd_s_ctrl(struct v4l2_ctrl *ctrl) { struct gspca_dev *gspca_dev = container_of(ctrl->handler, struct gspca_dev, ctrl_handler); struct sd *sd = (struct sd *)gspca_dev; int ret; sd->params.colourParams.brightness = val; sd->params.flickerControl.allowableOverExposure = find_over_exposure(sd->params.colourParams.brightness); if (gspca_dev->streaming) { ret = command_setcolourparams(gspca_dev); if (ret) return ret; return command_setflickerctrl(gspca_dev); } return 0; } static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; gspca_dev->usb_err = 0; *val = sd->params.colourParams.brightness; if (!gspca_dev->streaming && ctrl->id != V4L2_CID_POWER_LINE_FREQUENCY) return 0; } static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; sd->params.colourParams.contrast = val; if (gspca_dev->streaming) return command_setcolourparams(gspca_dev); return 0; } static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; *val = sd->params.colourParams.contrast; return 0; } static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; sd->params.colourParams.saturation = val; if (gspca_dev->streaming) return command_setcolourparams(gspca_dev); return 0; } static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; *val = sd->params.colourParams.saturation; return 0; } static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; int on; switch (val) { case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ on = 0; switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: sd->params.colourParams.brightness = ctrl->val; sd->params.flickerControl.allowableOverExposure = find_over_exposure(sd->params.colourParams.brightness); gspca_dev->usb_err = command_setcolourparams(gspca_dev); if (!gspca_dev->usb_err) gspca_dev->usb_err = command_setflickerctrl(gspca_dev); break; case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ on = 1; sd->mainsFreq = 0; case V4L2_CID_CONTRAST: sd->params.colourParams.contrast = ctrl->val; gspca_dev->usb_err = command_setcolourparams(gspca_dev); break; case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ on = 1; sd->mainsFreq = 1; case V4L2_CID_SATURATION: sd->params.colourParams.saturation = ctrl->val; gspca_dev->usb_err = command_setcolourparams(gspca_dev); break; default: return -EINVAL; } sd->freq = val; case V4L2_CID_POWER_LINE_FREQUENCY: sd->mainsFreq = ctrl->val == V4L2_CID_POWER_LINE_FREQUENCY_60HZ; sd->params.flickerControl.coarseJump = flicker_jumps[sd->mainsFreq] [sd->params.sensorFps.baserate] [sd->params.sensorFps.divisor]; return set_flicker(gspca_dev, on, gspca_dev->streaming); } static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; *val = sd->freq; return 0; } static int sd_setcomptarget(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; sd->params.compressionTarget.frTargeting = val; if (gspca_dev->streaming) return command_setcompressiontarget(gspca_dev); return 0; } static int sd_getcomptarget(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; *val = sd->params.compressionTarget.frTargeting; return 0; } static int sd_setilluminator(struct gspca_dev *gspca_dev, __s32 val, int n) { struct sd *sd = (struct sd *) gspca_dev; int ret; if (!sd->params.qx3.qx3_detected) return -EINVAL; switch (n) { case 1: sd->params.qx3.bottomlight = val ? 1 : 0; gspca_dev->usb_err = set_flicker(gspca_dev, ctrl->val != V4L2_CID_POWER_LINE_FREQUENCY_DISABLED, gspca_dev->streaming); break; case 2: sd->params.qx3.toplight = val ? 1 : 0; case V4L2_CID_ILLUMINATORS_1: sd->params.qx3.bottomlight = ctrl->val; gspca_dev->usb_err = command_setlights(gspca_dev); break; default: return -EINVAL; } ret = command_setlights(gspca_dev); if (ret && ret != -EINVAL) ret = -EBUSY; return ret; } static int sd_setilluminator1(struct gspca_dev *gspca_dev, __s32 val) { return sd_setilluminator(gspca_dev, val, 1); } static int sd_setilluminator2(struct gspca_dev *gspca_dev, __s32 val) { return sd_setilluminator(gspca_dev, val, 2); } static int sd_getilluminator(struct gspca_dev *gspca_dev, __s32 *val, int n) { struct sd *sd = (struct sd *) gspca_dev; if (!sd->params.qx3.qx3_detected) return -EINVAL; switch (n) { case 1: *val = sd->params.qx3.bottomlight; case V4L2_CID_ILLUMINATORS_2: sd->params.qx3.toplight = ctrl->val; gspca_dev->usb_err = command_setlights(gspca_dev); break; case 2: *val = sd->params.qx3.toplight; case CPIA1_CID_COMP_TARGET: sd->params.compressionTarget.frTargeting = ctrl->val; gspca_dev->usb_err = command_setcompressiontarget(gspca_dev); break; default: return -EINVAL; } return 0; return gspca_dev->usb_err; } static int sd_getilluminator1(struct gspca_dev *gspca_dev, __s32 *val) { return sd_getilluminator(gspca_dev, val, 1); } static const struct v4l2_ctrl_ops sd_ctrl_ops = { .s_ctrl = sd_s_ctrl, }; static int sd_getilluminator2(struct gspca_dev *gspca_dev, __s32 *val) static int sd_init_controls(struct gspca_dev *gspca_dev) { return sd_getilluminator(gspca_dev, val, 2); } struct sd *sd = (struct sd *)gspca_dev; struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; static const char * const comp_target_menu[] = { "Quality", "Framerate", NULL }; static const struct v4l2_ctrl_config comp_target = { .ops = &sd_ctrl_ops, .id = CPIA1_CID_COMP_TARGET, .type = V4L2_CTRL_TYPE_MENU, .name = "Compression Target", .qmenu = comp_target_menu, .max = 1, .def = COMP_TARGET_DEF, }; static int sd_querymenu(struct gspca_dev *gspca_dev, struct v4l2_querymenu *menu) { switch (menu->id) { case V4L2_CID_POWER_LINE_FREQUENCY: switch (menu->index) { case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ strcpy((char *) menu->name, "NoFliker"); return 0; case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ strcpy((char *) menu->name, "50 Hz"); return 0; case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ strcpy((char *) menu->name, "60 Hz"); return 0; gspca_dev->vdev.ctrl_handler = hdl; v4l2_ctrl_handler_init(hdl, 7); v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_BRIGHTNESS, 0, 100, 1, BRIGHTNESS_DEF); v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_CONTRAST, 0, 96, 8, CONTRAST_DEF); v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_SATURATION, 0, 100, 1, SATURATION_DEF); sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, V4L2_CID_POWER_LINE_FREQUENCY, V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, FREQ_DEF); if (sd->params.qx3.qx3_detected) { v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_ILLUMINATORS_1, 0, 1, 1, ILLUMINATORS_1_DEF); v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_ILLUMINATORS_2, 0, 1, 1, ILLUMINATORS_2_DEF); } v4l2_ctrl_new_custom(hdl, &comp_target, NULL); if (hdl->error) { pr_err("Could not initialize controls\n"); return hdl->error; } break; case V4L2_CID_COMP_TARGET: switch (menu->index) { case CPIA_COMPRESSION_TARGET_QUALITY: strcpy((char *) menu->name, "Quality"); return 0; case CPIA_COMPRESSION_TARGET_FRAMERATE: strcpy((char *) menu->name, "Framerate"); return 0; } break; } return -EINVAL; } /* sub-driver description */ static const struct sd_desc sd_desc = { .name = MODULE_NAME, .ctrls = sd_ctrls, .nctrls = ARRAY_SIZE(sd_ctrls), .config = sd_config, .init = sd_init, .init_controls = sd_init_controls, .start = sd_start, .stopN = sd_stopN, .dq_callback = sd_dq_callback, .pkt_scan = sd_pkt_scan, .querymenu = sd_querymenu, #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) .other_input = 1, #endif Loading