Loading drivers/media/usb/gspca/sonixj.c +164 −381 Original line number Diff line number Diff line Loading @@ -31,32 +31,26 @@ MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>"); MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); MODULE_LICENSE("GPL"); /* controls */ enum e_ctrl { BRIGHTNESS, CONTRAST, COLORS, BLUE, RED, GAMMA, EXPOSURE, AUTOGAIN, GAIN, HFLIP, VFLIP, SHARPNESS, ILLUM, FREQ, NCTRLS /* number of controls */ }; /* specific webcam descriptor */ struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ struct gspca_ctrl ctrls[NCTRLS]; atomic_t avg_lum; struct v4l2_ctrl *brightness; struct v4l2_ctrl *contrast; struct v4l2_ctrl *saturation; struct { /* red/blue balance control cluster */ struct v4l2_ctrl *red_bal; struct v4l2_ctrl *blue_bal; }; struct { /* hflip/vflip control cluster */ struct v4l2_ctrl *vflip; struct v4l2_ctrl *hflip; }; struct v4l2_ctrl *gamma; struct v4l2_ctrl *illum; struct v4l2_ctrl *sharpness; struct v4l2_ctrl *freq; u32 exposure; struct work_struct work; Loading Loading @@ -127,283 +121,6 @@ static void qual_upd(struct work_struct *work); #define SEN_CLK_EN 0x20 /* enable sensor clock */ #define DEF_EN 0x80 /* defect pixel by 0: soft, 1: hard */ /* V4L2 controls supported by the driver */ static void setbrightness(struct gspca_dev *gspca_dev); static void setcontrast(struct gspca_dev *gspca_dev); static void setcolors(struct gspca_dev *gspca_dev); static void setredblue(struct gspca_dev *gspca_dev); static void setgamma(struct gspca_dev *gspca_dev); static void setexposure(struct gspca_dev *gspca_dev); static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); static void setgain(struct gspca_dev *gspca_dev); static void sethvflip(struct gspca_dev *gspca_dev); static void setsharpness(struct gspca_dev *gspca_dev); static void setillum(struct gspca_dev *gspca_dev); static void setfreq(struct gspca_dev *gspca_dev); static const struct ctrl sd_ctrls[NCTRLS] = { [BRIGHTNESS] = { { .id = V4L2_CID_BRIGHTNESS, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Brightness", .minimum = 0, .maximum = 0xff, .step = 1, .default_value = 0x80, }, .set_control = setbrightness }, [CONTRAST] = { { .id = V4L2_CID_CONTRAST, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Contrast", .minimum = 0, #define CONTRAST_MAX 127 .maximum = CONTRAST_MAX, .step = 1, .default_value = 20, }, .set_control = setcontrast }, [COLORS] = { { .id = V4L2_CID_SATURATION, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Saturation", .minimum = 0, .maximum = 40, .step = 1, #define COLORS_DEF 25 .default_value = COLORS_DEF, }, .set_control = setcolors }, [BLUE] = { { .id = V4L2_CID_BLUE_BALANCE, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Blue Balance", .minimum = 24, .maximum = 40, .step = 1, .default_value = 32, }, .set_control = setredblue }, [RED] = { { .id = V4L2_CID_RED_BALANCE, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Red Balance", .minimum = 24, .maximum = 40, .step = 1, .default_value = 32, }, .set_control = setredblue }, [GAMMA] = { { .id = V4L2_CID_GAMMA, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Gamma", .minimum = 0, .maximum = 40, .step = 1, #define GAMMA_DEF 20 .default_value = GAMMA_DEF, }, .set_control = setgamma }, [EXPOSURE] = { { .id = V4L2_CID_EXPOSURE, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Exposure", .minimum = 500, .maximum = 1500, .step = 1, .default_value = 1024 }, .set_control = setexposure }, [AUTOGAIN] = { { .id = V4L2_CID_AUTOGAIN, .type = V4L2_CTRL_TYPE_BOOLEAN, .name = "Auto Gain", .minimum = 0, .maximum = 1, .step = 1, .default_value = 1 }, .set = sd_setautogain, }, [GAIN] = { { .id = V4L2_CID_GAIN, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Gain", .minimum = 4, .maximum = 49, .step = 1, .default_value = 15 }, .set_control = setgain }, [HFLIP] = { { .id = V4L2_CID_HFLIP, .type = V4L2_CTRL_TYPE_BOOLEAN, .name = "Mirror", .minimum = 0, .maximum = 1, .step = 1, .default_value = 0, }, .set_control = sethvflip }, [VFLIP] = { { .id = V4L2_CID_VFLIP, .type = V4L2_CTRL_TYPE_BOOLEAN, .name = "Vflip", .minimum = 0, .maximum = 1, .step = 1, .default_value = 0, }, .set_control = sethvflip }, [SHARPNESS] = { { .id = V4L2_CID_SHARPNESS, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Sharpness", .minimum = 0, .maximum = 255, .step = 1, .default_value = 90, }, .set_control = setsharpness }, [ILLUM] = { { .id = V4L2_CID_ILLUMINATORS_1, .type = V4L2_CTRL_TYPE_BOOLEAN, .name = "Illuminator / infrared", .minimum = 0, .maximum = 1, .step = 1, .default_value = 0, }, .set_control = setillum }, /* ov7630/ov7648/ov7660 only */ [FREQ] = { { .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, .default_value = 1, }, .set_control = setfreq }, }; /* table of the disabled controls */ static const __u32 ctrl_dis[] = { [SENSOR_ADCM1700] = (1 << EXPOSURE) | (1 << AUTOGAIN) | (1 << GAIN) | (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), [SENSOR_GC0307] = (1 << EXPOSURE) | (1 << GAIN) | (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), [SENSOR_HV7131R] = (1 << EXPOSURE) | (1 << GAIN) | (1 << HFLIP) | (1 << FREQ), [SENSOR_MI0360] = (1 << EXPOSURE) | (1 << GAIN) | (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), [SENSOR_MI0360B] = (1 << EXPOSURE) | (1 << GAIN) | (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), [SENSOR_MO4000] = (1 << EXPOSURE) | (1 << GAIN) | (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), [SENSOR_MT9V111] = (1 << EXPOSURE) | (1 << GAIN) | (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), [SENSOR_OM6802] = (1 << EXPOSURE) | (1 << GAIN) | (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), [SENSOR_OV7630] = (1 << EXPOSURE) | (1 << GAIN) | (1 << HFLIP), [SENSOR_OV7648] = (1 << EXPOSURE) | (1 << GAIN) | (1 << HFLIP), [SENSOR_OV7660] = (1 << EXPOSURE) | (1 << AUTOGAIN) | (1 << GAIN) | (1 << HFLIP) | (1 << VFLIP), [SENSOR_PO1030] = (1 << EXPOSURE) | (1 << AUTOGAIN) | (1 << GAIN) | (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), [SENSOR_PO2030N] = (1 << FREQ), [SENSOR_SOI768] = (1 << EXPOSURE) | (1 << AUTOGAIN) | (1 << GAIN) | (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), [SENSOR_SP80708] = (1 << EXPOSURE) | (1 << AUTOGAIN) | (1 << GAIN) | (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), }; static const struct v4l2_pix_format cif_mode[] = { {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 352, Loading Loading @@ -1822,7 +1539,6 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->nmodes = ARRAY_SIZE(vga_mode); } cam->npkt = 24; /* 24 packets per ISOC message */ cam->ctrls = sd->ctrls; sd->ag_cnt = -1; sd->quality = QUALITY_DEF; Loading Loading @@ -1888,9 +1604,6 @@ static int sd_init(struct gspca_dev *gspca_dev) break; } if (sd->sensor == SENSOR_OM6802) sd->ctrls[SHARPNESS].def = 0x10; /* Note we do not disable the sensor clock here (power saving mode), as that also disables the button on the cam. */ reg_w1(gspca_dev, 0xf1, 0x00); Loading @@ -1899,13 +1612,92 @@ static int sd_init(struct gspca_dev *gspca_dev) sn9c1xx = sn_tb[sd->sensor]; sd->i2c_addr = sn9c1xx[9]; gspca_dev->ctrl_dis = ctrl_dis[sd->sensor]; if (!(sd->flags & F_ILLUM)) gspca_dev->ctrl_dis |= (1 << ILLUM); return gspca_dev->usb_err; } static int sd_s_ctrl(struct v4l2_ctrl *ctrl); static const struct v4l2_ctrl_ops sd_ctrl_ops = { .s_ctrl = sd_s_ctrl, }; /* this function is called at probe time */ static int sd_init_controls(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; gspca_dev->vdev.ctrl_handler = hdl; v4l2_ctrl_handler_init(hdl, 14); sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); #define CONTRAST_MAX 127 sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_CONTRAST, 0, CONTRAST_MAX, 1, 20); #define COLORS_DEF 25 sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_SATURATION, 0, 40, 1, COLORS_DEF); sd->red_bal = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_RED_BALANCE, 24, 40, 1, 32); sd->blue_bal = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_BLUE_BALANCE, 24, 40, 1, 32); #define GAMMA_DEF 20 sd->gamma = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_GAMMA, 0, 40, 1, GAMMA_DEF); if (sd->sensor == SENSOR_OM6802) sd->sharpness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_SHARPNESS, 0, 255, 1, 16); else sd->sharpness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_SHARPNESS, 0, 255, 1, 90); if (sd->flags & F_ILLUM) sd->illum = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_ILLUMINATORS_1, 0, 1, 1, 0); if (sd->sensor == SENSOR_PO2030N) { gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_EXPOSURE, 500, 1500, 1, 1024); gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_GAIN, 4, 49, 1, 15); sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0); } if (sd->sensor != SENSOR_ADCM1700 && sd->sensor != SENSOR_OV7660 && sd->sensor != SENSOR_PO1030 && sd->sensor != SENSOR_SOI768 && sd->sensor != SENSOR_SP80708) gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_AUTOGAIN, 0, 1, 1, 1); if (sd->sensor == SENSOR_HV7131R || sd->sensor == SENSOR_OV7630 || sd->sensor == SENSOR_OV7648 || sd->sensor == SENSOR_PO2030N) sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0); if (sd->sensor == SENSOR_OV7630 || sd->sensor == SENSOR_OV7648 || sd->sensor == SENSOR_OV7660) sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, V4L2_CID_POWER_LINE_FREQUENCY, V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, V4L2_CID_POWER_LINE_FREQUENCY_50HZ); if (hdl->error) { pr_err("Could not initialize controls\n"); return hdl->error; } v4l2_ctrl_cluster(2, &sd->red_bal); if (sd->sensor == SENSOR_PO2030N) { v4l2_ctrl_cluster(2, &sd->vflip); v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false); } return 0; } static u32 expo_adjust(struct gspca_dev *gspca_dev, u32 expo) { Loading Loading @@ -2014,10 +1806,9 @@ static void setbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; unsigned int expo; int brightness; int brightness = sd->brightness->val; u8 k2; brightness = sd->ctrls[BRIGHTNESS].val; k2 = (brightness - 0x80) >> 2; switch (sd->sensor) { case SENSOR_ADCM1700: Loading Loading @@ -2064,7 +1855,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) u8 k2; u8 contrast[6]; k2 = sd->ctrls[CONTRAST].val * 37 / (CONTRAST_MAX + 1) k2 = sd->contrast->val * 37 / (CONTRAST_MAX + 1) + 37; /* 37..73 */ contrast[0] = (k2 + 1) / 2; /* red */ contrast[1] = 0; Loading @@ -2090,7 +1881,7 @@ static void setcolors(struct gspca_dev *gspca_dev) 60, -51, -9 /* VR VG VB */ }; colors = sd->ctrls[COLORS].val; colors = sd->saturation->val; if (sd->sensor == SENSOR_MI0360B) uv = uv_mi0360b; else Loading @@ -2112,14 +1903,14 @@ static void setredblue(struct gspca_dev *gspca_dev) {0xc1, 0x6e, 0x16, 0x00, 0x40, 0x00, 0x00, 0x10}; /* 0x40 = normal value = gain x 1 */ rg1b[3] = sd->ctrls[RED].val * 2; rg1b[5] = sd->ctrls[BLUE].val * 2; rg1b[3] = sd->red_bal->val * 2; rg1b[5] = sd->blue_bal->val * 2; i2c_w8(gspca_dev, rg1b); return; } reg_w1(gspca_dev, 0x05, sd->ctrls[RED].val); reg_w1(gspca_dev, 0x05, sd->red_bal->val); /* reg_w1(gspca_dev, 0x07, 32); */ reg_w1(gspca_dev, 0x06, sd->ctrls[BLUE].val); reg_w1(gspca_dev, 0x06, sd->blue_bal->val); } static void setgamma(struct gspca_dev *gspca_dev) Loading Loading @@ -2153,7 +1944,7 @@ static void setgamma(struct gspca_dev *gspca_dev) break; } val = sd->ctrls[GAMMA].val; val = sd->gamma->val; for (i = 0; i < sizeof gamma; i++) gamma[i] = gamma_base[i] + delta[i] * (val - GAMMA_DEF) / 32; Loading @@ -2168,11 +1959,11 @@ static void setexposure(struct gspca_dev *gspca_dev) u8 rexpo[] = /* 1a: expo H, 1b: expo M */ {0xa1, 0x6e, 0x1a, 0x00, 0x40, 0x00, 0x00, 0x10}; rexpo[3] = sd->ctrls[EXPOSURE].val >> 8; rexpo[3] = gspca_dev->exposure->val >> 8; i2c_w8(gspca_dev, rexpo); msleep(6); rexpo[2] = 0x1b; rexpo[3] = sd->ctrls[EXPOSURE].val; rexpo[3] = gspca_dev->exposure->val; i2c_w8(gspca_dev, rexpo); } } Loading @@ -2181,8 +1972,6 @@ static void setautogain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; if (gspca_dev->ctrl_dis & (1 << AUTOGAIN)) return; switch (sd->sensor) { case SENSOR_OV7630: case SENSOR_OV7648: { Loading @@ -2192,13 +1981,13 @@ static void setautogain(struct gspca_dev *gspca_dev) comb = 0xc0; else comb = 0xa0; if (sd->ctrls[AUTOGAIN].val) if (gspca_dev->autogain->val) comb |= 0x03; i2c_w1(&sd->gspca_dev, 0x13, comb); return; } } if (sd->ctrls[AUTOGAIN].val) if (gspca_dev->autogain->val) sd->ag_cnt = AG_CNT_START; else sd->ag_cnt = -1; Loading @@ -2212,7 +2001,7 @@ static void setgain(struct gspca_dev *gspca_dev) u8 rgain[] = /* 15: gain */ {0xa1, 0x6e, 0x15, 0x00, 0x40, 0x00, 0x00, 0x15}; rgain[3] = sd->ctrls[GAIN].val; rgain[3] = gspca_dev->gain->val; i2c_w8(gspca_dev, rgain); } } Loading @@ -2225,19 +2014,19 @@ static void sethvflip(struct gspca_dev *gspca_dev) switch (sd->sensor) { case SENSOR_HV7131R: comn = 0x18; /* clkdiv = 1, ablcen = 1 */ if (sd->ctrls[VFLIP].val) if (sd->vflip->val) comn |= 0x01; i2c_w1(gspca_dev, 0x01, comn); /* sctra */ break; case SENSOR_OV7630: comn = 0x02; if (!sd->ctrls[VFLIP].val) if (!sd->vflip->val) comn |= 0x80; i2c_w1(gspca_dev, 0x75, comn); break; case SENSOR_OV7648: comn = 0x06; if (sd->ctrls[VFLIP].val) if (sd->vflip->val) comn |= 0x80; i2c_w1(gspca_dev, 0x75, comn); break; Loading @@ -2251,9 +2040,9 @@ static void sethvflip(struct gspca_dev *gspca_dev) * bit3-0: X */ comn = 0x0a; if (sd->ctrls[HFLIP].val) if (sd->hflip->val) comn |= 0x80; if (sd->ctrls[VFLIP].val) if (sd->vflip->val) comn |= 0x40; i2c_w1(&sd->gspca_dev, 0x1e, comn); break; Loading @@ -2264,23 +2053,21 @@ static void setsharpness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; reg_w1(gspca_dev, 0x99, sd->ctrls[SHARPNESS].val); reg_w1(gspca_dev, 0x99, sd->sharpness->val); } static void setillum(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; if (gspca_dev->ctrl_dis & (1 << ILLUM)) return; switch (sd->sensor) { case SENSOR_ADCM1700: reg_w1(gspca_dev, 0x02, /* gpio */ sd->ctrls[ILLUM].val ? 0x64 : 0x60); sd->illum->val ? 0x64 : 0x60); break; case SENSOR_MT9V111: reg_w1(gspca_dev, 0x02, sd->ctrls[ILLUM].val ? 0x77 : 0x74); sd->illum->val ? 0x77 : 0x74); /* should have been: */ /* 0x55 : 0x54); * 370i */ /* 0x66 : 0x64); * Clip */ Loading @@ -2292,13 +2079,11 @@ static void setfreq(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; if (gspca_dev->ctrl_dis & (1 << FREQ)) return; if (sd->sensor == SENSOR_OV7660) { u8 com8; com8 = 0xdf; /* auto gain/wb/expo */ switch (sd->ctrls[FREQ].val) { switch (sd->freq->val) { case 0: /* Banding filter disabled */ i2c_w1(gspca_dev, 0x13, com8 | 0x20); break; Loading Loading @@ -2326,7 +2111,7 @@ static void setfreq(struct gspca_dev *gspca_dev) break; } switch (sd->ctrls[FREQ].val) { switch (sd->freq->val) { case 0: /* Banding filter disabled */ break; case 1: /* 50 hz (filter on and framerate adj) */ Loading Loading @@ -2698,17 +2483,6 @@ static int sd_start(struct gspca_dev *gspca_dev) sd->reg01 = reg01; sd->reg17 = reg17; sethvflip(gspca_dev); setbrightness(gspca_dev); setcontrast(gspca_dev); setcolors(gspca_dev); setautogain(gspca_dev); if (!(gspca_dev->ctrl_inac & ((1 << EXPOSURE) | (1 << GAIN)))) { setexposure(gspca_dev); setgain(gspca_dev); } setfreq(gspca_dev); sd->pktsz = sd->npkt = 0; sd->nchg = sd->short_mark = 0; sd->work_thread = create_singlethread_workqueue(MODULE_NAME); Loading Loading @@ -2803,9 +2577,6 @@ static void sd_stop0(struct gspca_dev *gspca_dev) } } #define WANT_REGULAR_AUTOGAIN #include "autogain_functions.h" static void do_autogain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; Loading @@ -2825,7 +2596,7 @@ static void do_autogain(struct gspca_dev *gspca_dev) PDEBUG(D_FRAM, "mean lum %d", delta); if (sd->sensor == SENSOR_PO2030N) { auto_gain_n_exposure(gspca_dev, delta, luma_mean, luma_delta, gspca_expo_autogain(gspca_dev, delta, luma_mean, luma_delta, 15, 1024); return; } Loading Loading @@ -3042,40 +2813,54 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, } } static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) static int sd_s_ctrl(struct v4l2_ctrl *ctrl) { struct sd *sd = (struct sd *) gspca_dev; struct gspca_dev *gspca_dev = container_of(ctrl->handler, struct gspca_dev, ctrl_handler); sd->ctrls[AUTOGAIN].val = val; if (val) gspca_dev->ctrl_inac |= (1 << EXPOSURE) | (1 << GAIN); else gspca_dev->ctrl_inac &= ~(1 << EXPOSURE) & ~(1 << GAIN); if (gspca_dev->streaming) setautogain(gspca_dev); return gspca_dev->usb_err; } gspca_dev->usb_err = 0; 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"); if (!gspca_dev->streaming) return 0; case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ strcpy((char *) menu->name, "60 Hz"); return 0; } switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: setbrightness(gspca_dev); break; } case V4L2_CID_CONTRAST: setcontrast(gspca_dev); break; case V4L2_CID_SATURATION: setcolors(gspca_dev); break; case V4L2_CID_RED_BALANCE: setredblue(gspca_dev); break; case V4L2_CID_GAMMA: setgamma(gspca_dev); break; case V4L2_CID_AUTOGAIN: setautogain(gspca_dev); setexposure(gspca_dev); setgain(gspca_dev); break; case V4L2_CID_VFLIP: sethvflip(gspca_dev); break; case V4L2_CID_SHARPNESS: setsharpness(gspca_dev); break; case V4L2_CID_ILLUMINATORS_1: setillum(gspca_dev); break; case V4L2_CID_POWER_LINE_FREQUENCY: setfreq(gspca_dev); break; default: return -EINVAL; } return gspca_dev->usb_err; } #if IS_ENABLED(CONFIG_INPUT) static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, Loading @@ -3099,16 +2884,14 @@ static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, /* sub-driver description */ static const struct sd_desc sd_desc = { .name = MODULE_NAME, .ctrls = sd_ctrls, .nctrls = NCTRLS, .config = sd_config, .init = sd_init, .init_controls = sd_init_controls, .start = sd_start, .stopN = sd_stopN, .stop0 = sd_stop0, .pkt_scan = sd_pkt_scan, .dq_callback = do_autogain, .querymenu = sd_querymenu, #if IS_ENABLED(CONFIG_INPUT) .int_pkt_scan = sd_int_pkt_scan, #endif Loading Loading
drivers/media/usb/gspca/sonixj.c +164 −381 Original line number Diff line number Diff line Loading @@ -31,32 +31,26 @@ MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>"); MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); MODULE_LICENSE("GPL"); /* controls */ enum e_ctrl { BRIGHTNESS, CONTRAST, COLORS, BLUE, RED, GAMMA, EXPOSURE, AUTOGAIN, GAIN, HFLIP, VFLIP, SHARPNESS, ILLUM, FREQ, NCTRLS /* number of controls */ }; /* specific webcam descriptor */ struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ struct gspca_ctrl ctrls[NCTRLS]; atomic_t avg_lum; struct v4l2_ctrl *brightness; struct v4l2_ctrl *contrast; struct v4l2_ctrl *saturation; struct { /* red/blue balance control cluster */ struct v4l2_ctrl *red_bal; struct v4l2_ctrl *blue_bal; }; struct { /* hflip/vflip control cluster */ struct v4l2_ctrl *vflip; struct v4l2_ctrl *hflip; }; struct v4l2_ctrl *gamma; struct v4l2_ctrl *illum; struct v4l2_ctrl *sharpness; struct v4l2_ctrl *freq; u32 exposure; struct work_struct work; Loading Loading @@ -127,283 +121,6 @@ static void qual_upd(struct work_struct *work); #define SEN_CLK_EN 0x20 /* enable sensor clock */ #define DEF_EN 0x80 /* defect pixel by 0: soft, 1: hard */ /* V4L2 controls supported by the driver */ static void setbrightness(struct gspca_dev *gspca_dev); static void setcontrast(struct gspca_dev *gspca_dev); static void setcolors(struct gspca_dev *gspca_dev); static void setredblue(struct gspca_dev *gspca_dev); static void setgamma(struct gspca_dev *gspca_dev); static void setexposure(struct gspca_dev *gspca_dev); static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); static void setgain(struct gspca_dev *gspca_dev); static void sethvflip(struct gspca_dev *gspca_dev); static void setsharpness(struct gspca_dev *gspca_dev); static void setillum(struct gspca_dev *gspca_dev); static void setfreq(struct gspca_dev *gspca_dev); static const struct ctrl sd_ctrls[NCTRLS] = { [BRIGHTNESS] = { { .id = V4L2_CID_BRIGHTNESS, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Brightness", .minimum = 0, .maximum = 0xff, .step = 1, .default_value = 0x80, }, .set_control = setbrightness }, [CONTRAST] = { { .id = V4L2_CID_CONTRAST, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Contrast", .minimum = 0, #define CONTRAST_MAX 127 .maximum = CONTRAST_MAX, .step = 1, .default_value = 20, }, .set_control = setcontrast }, [COLORS] = { { .id = V4L2_CID_SATURATION, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Saturation", .minimum = 0, .maximum = 40, .step = 1, #define COLORS_DEF 25 .default_value = COLORS_DEF, }, .set_control = setcolors }, [BLUE] = { { .id = V4L2_CID_BLUE_BALANCE, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Blue Balance", .minimum = 24, .maximum = 40, .step = 1, .default_value = 32, }, .set_control = setredblue }, [RED] = { { .id = V4L2_CID_RED_BALANCE, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Red Balance", .minimum = 24, .maximum = 40, .step = 1, .default_value = 32, }, .set_control = setredblue }, [GAMMA] = { { .id = V4L2_CID_GAMMA, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Gamma", .minimum = 0, .maximum = 40, .step = 1, #define GAMMA_DEF 20 .default_value = GAMMA_DEF, }, .set_control = setgamma }, [EXPOSURE] = { { .id = V4L2_CID_EXPOSURE, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Exposure", .minimum = 500, .maximum = 1500, .step = 1, .default_value = 1024 }, .set_control = setexposure }, [AUTOGAIN] = { { .id = V4L2_CID_AUTOGAIN, .type = V4L2_CTRL_TYPE_BOOLEAN, .name = "Auto Gain", .minimum = 0, .maximum = 1, .step = 1, .default_value = 1 }, .set = sd_setautogain, }, [GAIN] = { { .id = V4L2_CID_GAIN, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Gain", .minimum = 4, .maximum = 49, .step = 1, .default_value = 15 }, .set_control = setgain }, [HFLIP] = { { .id = V4L2_CID_HFLIP, .type = V4L2_CTRL_TYPE_BOOLEAN, .name = "Mirror", .minimum = 0, .maximum = 1, .step = 1, .default_value = 0, }, .set_control = sethvflip }, [VFLIP] = { { .id = V4L2_CID_VFLIP, .type = V4L2_CTRL_TYPE_BOOLEAN, .name = "Vflip", .minimum = 0, .maximum = 1, .step = 1, .default_value = 0, }, .set_control = sethvflip }, [SHARPNESS] = { { .id = V4L2_CID_SHARPNESS, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Sharpness", .minimum = 0, .maximum = 255, .step = 1, .default_value = 90, }, .set_control = setsharpness }, [ILLUM] = { { .id = V4L2_CID_ILLUMINATORS_1, .type = V4L2_CTRL_TYPE_BOOLEAN, .name = "Illuminator / infrared", .minimum = 0, .maximum = 1, .step = 1, .default_value = 0, }, .set_control = setillum }, /* ov7630/ov7648/ov7660 only */ [FREQ] = { { .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, .default_value = 1, }, .set_control = setfreq }, }; /* table of the disabled controls */ static const __u32 ctrl_dis[] = { [SENSOR_ADCM1700] = (1 << EXPOSURE) | (1 << AUTOGAIN) | (1 << GAIN) | (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), [SENSOR_GC0307] = (1 << EXPOSURE) | (1 << GAIN) | (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), [SENSOR_HV7131R] = (1 << EXPOSURE) | (1 << GAIN) | (1 << HFLIP) | (1 << FREQ), [SENSOR_MI0360] = (1 << EXPOSURE) | (1 << GAIN) | (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), [SENSOR_MI0360B] = (1 << EXPOSURE) | (1 << GAIN) | (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), [SENSOR_MO4000] = (1 << EXPOSURE) | (1 << GAIN) | (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), [SENSOR_MT9V111] = (1 << EXPOSURE) | (1 << GAIN) | (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), [SENSOR_OM6802] = (1 << EXPOSURE) | (1 << GAIN) | (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), [SENSOR_OV7630] = (1 << EXPOSURE) | (1 << GAIN) | (1 << HFLIP), [SENSOR_OV7648] = (1 << EXPOSURE) | (1 << GAIN) | (1 << HFLIP), [SENSOR_OV7660] = (1 << EXPOSURE) | (1 << AUTOGAIN) | (1 << GAIN) | (1 << HFLIP) | (1 << VFLIP), [SENSOR_PO1030] = (1 << EXPOSURE) | (1 << AUTOGAIN) | (1 << GAIN) | (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), [SENSOR_PO2030N] = (1 << FREQ), [SENSOR_SOI768] = (1 << EXPOSURE) | (1 << AUTOGAIN) | (1 << GAIN) | (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), [SENSOR_SP80708] = (1 << EXPOSURE) | (1 << AUTOGAIN) | (1 << GAIN) | (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), }; static const struct v4l2_pix_format cif_mode[] = { {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 352, Loading Loading @@ -1822,7 +1539,6 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->nmodes = ARRAY_SIZE(vga_mode); } cam->npkt = 24; /* 24 packets per ISOC message */ cam->ctrls = sd->ctrls; sd->ag_cnt = -1; sd->quality = QUALITY_DEF; Loading Loading @@ -1888,9 +1604,6 @@ static int sd_init(struct gspca_dev *gspca_dev) break; } if (sd->sensor == SENSOR_OM6802) sd->ctrls[SHARPNESS].def = 0x10; /* Note we do not disable the sensor clock here (power saving mode), as that also disables the button on the cam. */ reg_w1(gspca_dev, 0xf1, 0x00); Loading @@ -1899,13 +1612,92 @@ static int sd_init(struct gspca_dev *gspca_dev) sn9c1xx = sn_tb[sd->sensor]; sd->i2c_addr = sn9c1xx[9]; gspca_dev->ctrl_dis = ctrl_dis[sd->sensor]; if (!(sd->flags & F_ILLUM)) gspca_dev->ctrl_dis |= (1 << ILLUM); return gspca_dev->usb_err; } static int sd_s_ctrl(struct v4l2_ctrl *ctrl); static const struct v4l2_ctrl_ops sd_ctrl_ops = { .s_ctrl = sd_s_ctrl, }; /* this function is called at probe time */ static int sd_init_controls(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; gspca_dev->vdev.ctrl_handler = hdl; v4l2_ctrl_handler_init(hdl, 14); sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); #define CONTRAST_MAX 127 sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_CONTRAST, 0, CONTRAST_MAX, 1, 20); #define COLORS_DEF 25 sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_SATURATION, 0, 40, 1, COLORS_DEF); sd->red_bal = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_RED_BALANCE, 24, 40, 1, 32); sd->blue_bal = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_BLUE_BALANCE, 24, 40, 1, 32); #define GAMMA_DEF 20 sd->gamma = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_GAMMA, 0, 40, 1, GAMMA_DEF); if (sd->sensor == SENSOR_OM6802) sd->sharpness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_SHARPNESS, 0, 255, 1, 16); else sd->sharpness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_SHARPNESS, 0, 255, 1, 90); if (sd->flags & F_ILLUM) sd->illum = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_ILLUMINATORS_1, 0, 1, 1, 0); if (sd->sensor == SENSOR_PO2030N) { gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_EXPOSURE, 500, 1500, 1, 1024); gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_GAIN, 4, 49, 1, 15); sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0); } if (sd->sensor != SENSOR_ADCM1700 && sd->sensor != SENSOR_OV7660 && sd->sensor != SENSOR_PO1030 && sd->sensor != SENSOR_SOI768 && sd->sensor != SENSOR_SP80708) gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_AUTOGAIN, 0, 1, 1, 1); if (sd->sensor == SENSOR_HV7131R || sd->sensor == SENSOR_OV7630 || sd->sensor == SENSOR_OV7648 || sd->sensor == SENSOR_PO2030N) sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0); if (sd->sensor == SENSOR_OV7630 || sd->sensor == SENSOR_OV7648 || sd->sensor == SENSOR_OV7660) sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, V4L2_CID_POWER_LINE_FREQUENCY, V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, V4L2_CID_POWER_LINE_FREQUENCY_50HZ); if (hdl->error) { pr_err("Could not initialize controls\n"); return hdl->error; } v4l2_ctrl_cluster(2, &sd->red_bal); if (sd->sensor == SENSOR_PO2030N) { v4l2_ctrl_cluster(2, &sd->vflip); v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false); } return 0; } static u32 expo_adjust(struct gspca_dev *gspca_dev, u32 expo) { Loading Loading @@ -2014,10 +1806,9 @@ static void setbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; unsigned int expo; int brightness; int brightness = sd->brightness->val; u8 k2; brightness = sd->ctrls[BRIGHTNESS].val; k2 = (brightness - 0x80) >> 2; switch (sd->sensor) { case SENSOR_ADCM1700: Loading Loading @@ -2064,7 +1855,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) u8 k2; u8 contrast[6]; k2 = sd->ctrls[CONTRAST].val * 37 / (CONTRAST_MAX + 1) k2 = sd->contrast->val * 37 / (CONTRAST_MAX + 1) + 37; /* 37..73 */ contrast[0] = (k2 + 1) / 2; /* red */ contrast[1] = 0; Loading @@ -2090,7 +1881,7 @@ static void setcolors(struct gspca_dev *gspca_dev) 60, -51, -9 /* VR VG VB */ }; colors = sd->ctrls[COLORS].val; colors = sd->saturation->val; if (sd->sensor == SENSOR_MI0360B) uv = uv_mi0360b; else Loading @@ -2112,14 +1903,14 @@ static void setredblue(struct gspca_dev *gspca_dev) {0xc1, 0x6e, 0x16, 0x00, 0x40, 0x00, 0x00, 0x10}; /* 0x40 = normal value = gain x 1 */ rg1b[3] = sd->ctrls[RED].val * 2; rg1b[5] = sd->ctrls[BLUE].val * 2; rg1b[3] = sd->red_bal->val * 2; rg1b[5] = sd->blue_bal->val * 2; i2c_w8(gspca_dev, rg1b); return; } reg_w1(gspca_dev, 0x05, sd->ctrls[RED].val); reg_w1(gspca_dev, 0x05, sd->red_bal->val); /* reg_w1(gspca_dev, 0x07, 32); */ reg_w1(gspca_dev, 0x06, sd->ctrls[BLUE].val); reg_w1(gspca_dev, 0x06, sd->blue_bal->val); } static void setgamma(struct gspca_dev *gspca_dev) Loading Loading @@ -2153,7 +1944,7 @@ static void setgamma(struct gspca_dev *gspca_dev) break; } val = sd->ctrls[GAMMA].val; val = sd->gamma->val; for (i = 0; i < sizeof gamma; i++) gamma[i] = gamma_base[i] + delta[i] * (val - GAMMA_DEF) / 32; Loading @@ -2168,11 +1959,11 @@ static void setexposure(struct gspca_dev *gspca_dev) u8 rexpo[] = /* 1a: expo H, 1b: expo M */ {0xa1, 0x6e, 0x1a, 0x00, 0x40, 0x00, 0x00, 0x10}; rexpo[3] = sd->ctrls[EXPOSURE].val >> 8; rexpo[3] = gspca_dev->exposure->val >> 8; i2c_w8(gspca_dev, rexpo); msleep(6); rexpo[2] = 0x1b; rexpo[3] = sd->ctrls[EXPOSURE].val; rexpo[3] = gspca_dev->exposure->val; i2c_w8(gspca_dev, rexpo); } } Loading @@ -2181,8 +1972,6 @@ static void setautogain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; if (gspca_dev->ctrl_dis & (1 << AUTOGAIN)) return; switch (sd->sensor) { case SENSOR_OV7630: case SENSOR_OV7648: { Loading @@ -2192,13 +1981,13 @@ static void setautogain(struct gspca_dev *gspca_dev) comb = 0xc0; else comb = 0xa0; if (sd->ctrls[AUTOGAIN].val) if (gspca_dev->autogain->val) comb |= 0x03; i2c_w1(&sd->gspca_dev, 0x13, comb); return; } } if (sd->ctrls[AUTOGAIN].val) if (gspca_dev->autogain->val) sd->ag_cnt = AG_CNT_START; else sd->ag_cnt = -1; Loading @@ -2212,7 +2001,7 @@ static void setgain(struct gspca_dev *gspca_dev) u8 rgain[] = /* 15: gain */ {0xa1, 0x6e, 0x15, 0x00, 0x40, 0x00, 0x00, 0x15}; rgain[3] = sd->ctrls[GAIN].val; rgain[3] = gspca_dev->gain->val; i2c_w8(gspca_dev, rgain); } } Loading @@ -2225,19 +2014,19 @@ static void sethvflip(struct gspca_dev *gspca_dev) switch (sd->sensor) { case SENSOR_HV7131R: comn = 0x18; /* clkdiv = 1, ablcen = 1 */ if (sd->ctrls[VFLIP].val) if (sd->vflip->val) comn |= 0x01; i2c_w1(gspca_dev, 0x01, comn); /* sctra */ break; case SENSOR_OV7630: comn = 0x02; if (!sd->ctrls[VFLIP].val) if (!sd->vflip->val) comn |= 0x80; i2c_w1(gspca_dev, 0x75, comn); break; case SENSOR_OV7648: comn = 0x06; if (sd->ctrls[VFLIP].val) if (sd->vflip->val) comn |= 0x80; i2c_w1(gspca_dev, 0x75, comn); break; Loading @@ -2251,9 +2040,9 @@ static void sethvflip(struct gspca_dev *gspca_dev) * bit3-0: X */ comn = 0x0a; if (sd->ctrls[HFLIP].val) if (sd->hflip->val) comn |= 0x80; if (sd->ctrls[VFLIP].val) if (sd->vflip->val) comn |= 0x40; i2c_w1(&sd->gspca_dev, 0x1e, comn); break; Loading @@ -2264,23 +2053,21 @@ static void setsharpness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; reg_w1(gspca_dev, 0x99, sd->ctrls[SHARPNESS].val); reg_w1(gspca_dev, 0x99, sd->sharpness->val); } static void setillum(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; if (gspca_dev->ctrl_dis & (1 << ILLUM)) return; switch (sd->sensor) { case SENSOR_ADCM1700: reg_w1(gspca_dev, 0x02, /* gpio */ sd->ctrls[ILLUM].val ? 0x64 : 0x60); sd->illum->val ? 0x64 : 0x60); break; case SENSOR_MT9V111: reg_w1(gspca_dev, 0x02, sd->ctrls[ILLUM].val ? 0x77 : 0x74); sd->illum->val ? 0x77 : 0x74); /* should have been: */ /* 0x55 : 0x54); * 370i */ /* 0x66 : 0x64); * Clip */ Loading @@ -2292,13 +2079,11 @@ static void setfreq(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; if (gspca_dev->ctrl_dis & (1 << FREQ)) return; if (sd->sensor == SENSOR_OV7660) { u8 com8; com8 = 0xdf; /* auto gain/wb/expo */ switch (sd->ctrls[FREQ].val) { switch (sd->freq->val) { case 0: /* Banding filter disabled */ i2c_w1(gspca_dev, 0x13, com8 | 0x20); break; Loading Loading @@ -2326,7 +2111,7 @@ static void setfreq(struct gspca_dev *gspca_dev) break; } switch (sd->ctrls[FREQ].val) { switch (sd->freq->val) { case 0: /* Banding filter disabled */ break; case 1: /* 50 hz (filter on and framerate adj) */ Loading Loading @@ -2698,17 +2483,6 @@ static int sd_start(struct gspca_dev *gspca_dev) sd->reg01 = reg01; sd->reg17 = reg17; sethvflip(gspca_dev); setbrightness(gspca_dev); setcontrast(gspca_dev); setcolors(gspca_dev); setautogain(gspca_dev); if (!(gspca_dev->ctrl_inac & ((1 << EXPOSURE) | (1 << GAIN)))) { setexposure(gspca_dev); setgain(gspca_dev); } setfreq(gspca_dev); sd->pktsz = sd->npkt = 0; sd->nchg = sd->short_mark = 0; sd->work_thread = create_singlethread_workqueue(MODULE_NAME); Loading Loading @@ -2803,9 +2577,6 @@ static void sd_stop0(struct gspca_dev *gspca_dev) } } #define WANT_REGULAR_AUTOGAIN #include "autogain_functions.h" static void do_autogain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; Loading @@ -2825,7 +2596,7 @@ static void do_autogain(struct gspca_dev *gspca_dev) PDEBUG(D_FRAM, "mean lum %d", delta); if (sd->sensor == SENSOR_PO2030N) { auto_gain_n_exposure(gspca_dev, delta, luma_mean, luma_delta, gspca_expo_autogain(gspca_dev, delta, luma_mean, luma_delta, 15, 1024); return; } Loading Loading @@ -3042,40 +2813,54 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, } } static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) static int sd_s_ctrl(struct v4l2_ctrl *ctrl) { struct sd *sd = (struct sd *) gspca_dev; struct gspca_dev *gspca_dev = container_of(ctrl->handler, struct gspca_dev, ctrl_handler); sd->ctrls[AUTOGAIN].val = val; if (val) gspca_dev->ctrl_inac |= (1 << EXPOSURE) | (1 << GAIN); else gspca_dev->ctrl_inac &= ~(1 << EXPOSURE) & ~(1 << GAIN); if (gspca_dev->streaming) setautogain(gspca_dev); return gspca_dev->usb_err; } gspca_dev->usb_err = 0; 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"); if (!gspca_dev->streaming) return 0; case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ strcpy((char *) menu->name, "60 Hz"); return 0; } switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: setbrightness(gspca_dev); break; } case V4L2_CID_CONTRAST: setcontrast(gspca_dev); break; case V4L2_CID_SATURATION: setcolors(gspca_dev); break; case V4L2_CID_RED_BALANCE: setredblue(gspca_dev); break; case V4L2_CID_GAMMA: setgamma(gspca_dev); break; case V4L2_CID_AUTOGAIN: setautogain(gspca_dev); setexposure(gspca_dev); setgain(gspca_dev); break; case V4L2_CID_VFLIP: sethvflip(gspca_dev); break; case V4L2_CID_SHARPNESS: setsharpness(gspca_dev); break; case V4L2_CID_ILLUMINATORS_1: setillum(gspca_dev); break; case V4L2_CID_POWER_LINE_FREQUENCY: setfreq(gspca_dev); break; default: return -EINVAL; } return gspca_dev->usb_err; } #if IS_ENABLED(CONFIG_INPUT) static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, Loading @@ -3099,16 +2884,14 @@ static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, /* sub-driver description */ static const struct sd_desc sd_desc = { .name = MODULE_NAME, .ctrls = sd_ctrls, .nctrls = NCTRLS, .config = sd_config, .init = sd_init, .init_controls = sd_init_controls, .start = sd_start, .stopN = sd_stopN, .stop0 = sd_stop0, .pkt_scan = sd_pkt_scan, .dq_callback = do_autogain, .querymenu = sd_querymenu, #if IS_ENABLED(CONFIG_INPUT) .int_pkt_scan = sd_int_pkt_scan, #endif Loading