Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] gspca - sonixb: Use the new control mechanism

Acked-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Jean-François Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

authored by

Jean-François Moine and committed by
Mauro Carvalho Chehab
f51a8caa fa85bb6f

+93 -193
+93 -193
drivers/media/video/gspca/sonixb.c
··· 56 56 MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver"); 57 57 MODULE_LICENSE("GPL"); 58 58 59 + /* controls */ 60 + enum e_ctrl { 61 + BRIGHTNESS, 62 + GAIN, 63 + EXPOSURE, 64 + AUTOGAIN, 65 + FREQ, 66 + NCTRLS /* number of controls */ 67 + }; 68 + 59 69 /* specific webcam descriptor */ 60 70 struct sd { 61 71 struct gspca_dev gspca_dev; /* !! must be the first item */ 72 + 73 + struct gspca_ctrl ctrls[NCTRLS]; 74 + 62 75 atomic_t avg_lum; 63 76 int prev_avg_lum; 64 77 int exp_too_low_cnt; ··· 79 66 int header_read; 80 67 u8 header[12]; /* Header without sof marker */ 81 68 82 - unsigned short exposure; 83 - unsigned char gain; 84 - unsigned char brightness; 85 - unsigned char autogain; 86 69 unsigned char autogain_ignore_frames; 87 70 unsigned char frames_to_drop; 88 - unsigned char freq; /* light freq filter setting */ 89 71 90 72 __u8 bridge; /* Type of bridge */ 91 73 #define BRIDGE_101 0 ··· 121 113 #define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */ 122 114 123 115 /* ctrl_dis helper macros */ 124 - #define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << COARSE_EXPOSURE_IDX) | \ 125 - (1 << AUTOGAIN_IDX)) 126 - #define NO_FREQ (1 << FREQ_IDX) 127 - #define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX) 116 + #define NO_EXPO ((1 << EXPOSURE) | (1 << AUTOGAIN)) 117 + #define NO_FREQ (1 << FREQ) 118 + #define NO_BRIGHTNESS (1 << BRIGHTNESS) 128 119 129 120 #define COMP 0xc7 /* 0x87 //0x07 */ 130 121 #define COMP1 0xc9 /* 0x89 //0x09 */ ··· 148 141 #define AUTOGAIN_IGNORE_FRAMES 1 149 142 150 143 /* V4L2 controls supported by the driver */ 151 - static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); 152 - static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 153 - static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); 154 - static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); 155 - static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); 156 - static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); 144 + static void setbrightness(struct gspca_dev *gspca_dev); 145 + static void setgain(struct gspca_dev *gspca_dev); 146 + static void setexposure(struct gspca_dev *gspca_dev); 157 147 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 158 - static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); 159 - static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); 160 - static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); 148 + static void setfreq(struct gspca_dev *gspca_dev); 161 149 162 - static const struct ctrl sd_ctrls[] = { 163 - #define BRIGHTNESS_IDX 0 164 - { 150 + static const struct ctrl sd_ctrls[NCTRLS] = { 151 + [BRIGHTNESS] = { 165 152 { 166 153 .id = V4L2_CID_BRIGHTNESS, 167 154 .type = V4L2_CTRL_TYPE_INTEGER, ··· 163 162 .minimum = 0, 164 163 .maximum = 255, 165 164 .step = 1, 166 - #define BRIGHTNESS_DEF 127 167 - .default_value = BRIGHTNESS_DEF, 165 + .default_value = 127, 168 166 }, 169 - .set = sd_setbrightness, 170 - .get = sd_getbrightness, 167 + .set_control = setbrightness 171 168 }, 172 - #define GAIN_IDX 1 173 - { 169 + [GAIN] = { 174 170 { 175 171 .id = V4L2_CID_GAIN, 176 172 .type = V4L2_CTRL_TYPE_INTEGER, ··· 175 177 .minimum = 0, 176 178 .maximum = 255, 177 179 .step = 1, 178 - #define GAIN_DEF 127 179 180 #define GAIN_KNEE 230 180 - .default_value = GAIN_DEF, 181 + .default_value = 127, 181 182 }, 182 - .set = sd_setgain, 183 - .get = sd_getgain, 183 + .set_control = setgain 184 184 }, 185 - #define EXPOSURE_IDX 2 186 - { 185 + [EXPOSURE] = { 187 186 { 188 187 .id = V4L2_CID_EXPOSURE, 189 188 .type = V4L2_CTRL_TYPE_INTEGER, 190 189 .name = "Exposure", 191 - #define EXPOSURE_DEF 66 /* 33 ms / 30 fps (except on PASXXX) */ 192 - #define EXPOSURE_KNEE 200 /* 100 ms / 10 fps (except on PASXXX) */ 193 190 .minimum = 0, 194 191 .maximum = 1023, 195 192 .step = 1, 196 - .default_value = EXPOSURE_DEF, 193 + .default_value = 66, 194 + /* 33 ms / 30 fps (except on PASXXX) */ 195 + #define EXPOSURE_KNEE 200 /* 100 ms / 10 fps (except on PASXXX) */ 197 196 .flags = 0, 198 197 }, 199 - .set = sd_setexposure, 200 - .get = sd_getexposure, 198 + .set_control = setexposure 201 199 }, 202 - #define COARSE_EXPOSURE_IDX 3 203 - { 204 - { 205 - .id = V4L2_CID_EXPOSURE, 206 - .type = V4L2_CTRL_TYPE_INTEGER, 207 - .name = "Exposure", 200 + /* for coarse exposure */ 201 + #define COARSE_EXPOSURE_MIN 2 202 + #define COARSE_EXPOSURE_MAX 15 208 203 #define COARSE_EXPOSURE_DEF 2 /* 30 fps */ 209 - .minimum = 2, 210 - .maximum = 15, 211 - .step = 1, 212 - .default_value = COARSE_EXPOSURE_DEF, 213 - .flags = 0, 214 - }, 215 - .set = sd_setexposure, 216 - .get = sd_getexposure, 217 - }, 218 - #define AUTOGAIN_IDX 4 219 - { 204 + [AUTOGAIN] = { 220 205 { 221 206 .id = V4L2_CID_AUTOGAIN, 222 207 .type = V4L2_CTRL_TYPE_BOOLEAN, ··· 212 231 .flags = 0, 213 232 }, 214 233 .set = sd_setautogain, 215 - .get = sd_getautogain, 216 234 }, 217 - #define FREQ_IDX 5 218 - { 235 + [FREQ] = { 219 236 { 220 237 .id = V4L2_CID_POWER_LINE_FREQUENCY, 221 238 .type = V4L2_CTRL_TYPE_MENU, ··· 224 245 #define FREQ_DEF 0 225 246 .default_value = FREQ_DEF, 226 247 }, 227 - .set = sd_setfreq, 228 - .get = sd_getfreq, 248 + .set_control = setfreq 229 249 }, 230 250 }; 231 251 ··· 624 646 625 647 /* change reg 0x06 */ 626 648 i2cOV[1] = sensor_data[sd->sensor].sensor_addr; 627 - i2cOV[3] = sd->brightness; 649 + i2cOV[3] = sd->ctrls[BRIGHTNESS].val; 628 650 if (i2c_w(gspca_dev, i2cOV) < 0) 629 651 goto err; 630 652 break; ··· 642 664 i2cpdoit[2] = 0x13; 643 665 } 644 666 645 - if (sd->brightness < 127) { 667 + if (sd->ctrls[BRIGHTNESS].val < 127) { 646 668 /* change reg 0x0b, signreg */ 647 669 i2cpbright[3] = 0x01; 648 670 /* set reg 0x0c, offset */ 649 - i2cpbright[4] = 127 - sd->brightness; 671 + i2cpbright[4] = 127 - sd->ctrls[BRIGHTNESS].val; 650 672 } else 651 - i2cpbright[4] = sd->brightness - 127; 673 + i2cpbright[4] = sd->ctrls[BRIGHTNESS].val - 127; 652 674 653 675 if (i2c_w(gspca_dev, i2cpbright) < 0) 654 676 goto err; ··· 665 687 static void setsensorgain(struct gspca_dev *gspca_dev) 666 688 { 667 689 struct sd *sd = (struct sd *) gspca_dev; 668 - unsigned char gain = sd->gain; 690 + u8 gain = sd->ctrls[GAIN].val; 669 691 670 692 switch (sd->sensor) { 671 693 case SENSOR_HV7131D: { 672 694 __u8 i2c[] = 673 695 {0xc0, 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x17}; 674 696 675 - i2c[3] = 0x3f - (sd->gain / 4); 676 - i2c[4] = 0x3f - (sd->gain / 4); 677 - i2c[5] = 0x3f - (sd->gain / 4); 697 + i2c[3] = 0x3f - (gain / 4); 698 + i2c[4] = 0x3f - (gain / 4); 699 + i2c[5] = 0x3f - (gain / 4); 678 700 679 701 if (i2c_w(gspca_dev, i2c) < 0) 680 702 goto err; ··· 737 759 i2cpdoit[2] = 0x13; 738 760 } 739 761 740 - i2cpgain[3] = sd->gain >> 3; 741 - i2cpcolorgain[3] = sd->gain >> 4; 742 - i2cpcolorgain[4] = sd->gain >> 4; 743 - i2cpcolorgain[5] = sd->gain >> 4; 744 - i2cpcolorgain[6] = sd->gain >> 4; 762 + i2cpgain[3] = gain >> 3; 763 + i2cpcolorgain[3] = gain >> 4; 764 + i2cpcolorgain[4] = gain >> 4; 765 + i2cpcolorgain[5] = gain >> 4; 766 + i2cpcolorgain[6] = gain >> 4; 745 767 746 768 if (i2c_w(gspca_dev, i2cpgain) < 0) 747 769 goto err; ··· 770 792 } 771 793 772 794 if (sd->bridge == BRIDGE_103) { 773 - gain = sd->gain >> 1; 795 + gain = sd->ctrls[GAIN].val >> 1; 774 796 buf[0] = gain; /* Red */ 775 797 buf[1] = gain; /* Green */ 776 798 buf[2] = gain; /* Blue */ 777 799 reg_w(gspca_dev, 0x05, buf, 3); 778 800 } else { 779 - gain = sd->gain >> 4; 801 + gain = sd->ctrls[GAIN].val >> 4; 780 802 buf[0] = gain << 4 | gain; /* Red and blue */ 781 803 buf[1] = gain; /* Green */ 782 804 reg_w(gspca_dev, 0x10, buf, 2); ··· 798 820 where the framerate starts dropping 799 821 2) At 6138 the framerate has already dropped to 2 fps, 800 822 going any lower makes little sense */ 801 - __u16 reg = sd->exposure * 6; 823 + u16 reg = sd->ctrls[EXPOSURE].val * 6; 824 + 802 825 i2c[3] = reg >> 8; 803 826 i2c[4] = reg & 0xff; 804 827 if (i2c_w(gspca_dev, i2c) != 0) ··· 811 832 /* register 19's high nibble contains the sn9c10x clock divider 812 833 The high nibble configures the no fps according to the 813 834 formula: 60 / high_nibble. With a maximum of 30 fps */ 814 - __u8 reg = sd->exposure; 835 + u8 reg = sd->ctrls[EXPOSURE].val; 836 + 815 837 reg = (reg << 4) | 0x0b; 816 838 reg_w(gspca_dev, 0x19, &reg, 1); 817 839 break; ··· 848 868 } else 849 869 reg10_max = 0x41; 850 870 851 - reg11 = (15 * sd->exposure + 999) / 1000; 871 + reg11 = (15 * sd->ctrls[EXPOSURE].val + 999) / 1000; 852 872 if (reg11 < 1) 853 873 reg11 = 1; 854 874 else if (reg11 > 16) ··· 861 881 reg11 = 4; 862 882 863 883 /* frame exposure time in ms = 1000 * reg11 / 30 -> 864 - reg10 = (sd->exposure / 2) * reg10_max / (1000 * reg11 / 30) */ 865 - reg10 = (sd->exposure * 15 * reg10_max) / (1000 * reg11); 884 + reg10 = (sd->ctrls[EXPOSURE].val / 2) * reg10_max 885 + / (1000 * reg11 / 30) */ 886 + reg10 = (sd->ctrls[EXPOSURE].val * 15 * reg10_max) 887 + / (1000 * reg11); 866 888 867 889 /* Don't allow this to get below 10 when using autogain, the 868 890 steps become very large (relatively) when below 10 causing 869 891 the image to oscilate from much too dark, to much too bright 870 892 and back again. */ 871 - if (sd->autogain && reg10 < 10) 893 + if (sd->ctrls[AUTOGAIN].val && reg10 < 10) 872 894 reg10 = 10; 873 895 else if (reg10 > reg10_max) 874 896 reg10 = reg10_max; ··· 909 927 frame exposure times (like we are doing with the ov chips), 910 928 as that sometimes leads to jumps in the exposure control, 911 929 which are bad for auto exposure. */ 912 - if (sd->exposure < 200) { 913 - i2cpexpo[3] = 255 - (sd->exposure * 255) / 200; 930 + if (sd->ctrls[EXPOSURE].val < 200) { 931 + i2cpexpo[3] = 255 - (sd->ctrls[EXPOSURE].val * 255) 932 + / 200; 914 933 framerate_ctrl = 500; 915 934 } else { 916 935 /* The PAS202's exposure control goes from 0 - 4095, 917 936 but anything below 500 causes vsync issues, so scale 918 937 our 200-1023 to 500-4095 */ 919 - framerate_ctrl = (sd->exposure - 200) * 1000 / 229 + 920 - 500; 938 + framerate_ctrl = (sd->ctrls[EXPOSURE].val - 200) 939 + * 1000 / 229 + 500; 921 940 } 922 941 923 942 i2cpframerate[3] = framerate_ctrl >> 6; ··· 942 959 943 960 /* For values below 150 use partial frame exposure, above 944 961 that use framerate ctrl */ 945 - if (sd->exposure < 150) { 946 - i2cpexpo[3] = 150 - sd->exposure; 962 + if (sd->ctrls[EXPOSURE].val < 150) { 963 + i2cpexpo[3] = 150 - sd->ctrls[EXPOSURE].val; 947 964 framerate_ctrl = 300; 948 965 } else { 949 966 /* The PAS106's exposure control goes from 0 - 4095, 950 967 but anything below 300 causes vsync issues, so scale 951 968 our 150-1023 to 300-4095 */ 952 - framerate_ctrl = (sd->exposure - 150) * 1000 / 230 + 953 - 300; 969 + framerate_ctrl = (sd->ctrls[EXPOSURE].val - 150) 970 + * 1000 / 230 + 300; 954 971 } 955 972 956 973 i2cpframerate[3] = framerate_ctrl >> 4; ··· 981 998 0x2b register, see ov6630 datasheet. 982 999 0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */ 983 1000 __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}; 984 - switch (sd->freq) { 1001 + switch (sd->ctrls[FREQ].val) { 985 1002 default: 986 1003 /* case 0: * no filter*/ 987 1004 /* case 2: * 60 hz */ ··· 1000 1017 } 1001 1018 } 1002 1019 1003 - #include "coarse_expo_autogain.h" 1020 + #include "autogain_functions.h" 1004 1021 1005 1022 static void do_autogain(struct gspca_dev *gspca_dev) 1006 1023 { ··· 1008 1025 struct sd *sd = (struct sd *) gspca_dev; 1009 1026 int avg_lum = atomic_read(&sd->avg_lum); 1010 1027 1011 - if (avg_lum == -1 || !sd->autogain) 1028 + if (avg_lum == -1 || !sd->ctrls[AUTOGAIN].val) 1012 1029 return; 1013 1030 1014 1031 if (sd->autogain_ignore_frames > 0) { ··· 1028 1045 } 1029 1046 1030 1047 if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) 1031 - result = gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum, 1032 - sd->brightness * desired_avg_lum / 127, 1048 + result = coarse_grained_expo_autogain(gspca_dev, avg_lum, 1049 + sd->ctrls[BRIGHTNESS].val 1050 + * desired_avg_lum / 127, 1033 1051 deadzone); 1034 1052 else 1035 - result = gspca_auto_gain_n_exposure(gspca_dev, avg_lum, 1036 - sd->brightness * desired_avg_lum / 127, 1053 + result = auto_gain_n_exposure(gspca_dev, avg_lum, 1054 + sd->ctrls[BRIGHTNESS].val 1055 + * desired_avg_lum / 127, 1037 1056 deadzone, GAIN_KNEE, EXPOSURE_KNEE); 1038 1057 1039 1058 if (result) { 1040 1059 PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d", 1041 - (int)sd->gain, (int)sd->exposure); 1060 + (int) sd->ctrls[GAIN].val, 1061 + (int) sd->ctrls[EXPOSURE].val); 1042 1062 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; 1043 1063 } 1044 1064 } ··· 1060 1074 /* copy the webcam info from the device id */ 1061 1075 sd->sensor = id->driver_info >> 8; 1062 1076 sd->bridge = id->driver_info & 0xff; 1077 + 1063 1078 gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis; 1064 1079 1065 1080 cam = &gspca_dev->cam; 1081 + cam->ctrls = sd->ctrls; 1066 1082 if (!(sensor_data[sd->sensor].flags & F_SIF)) { 1067 1083 cam->cam_mode = vga_mode; 1068 1084 cam->nmodes = ARRAY_SIZE(vga_mode); ··· 1074 1086 } 1075 1087 cam->npkt = 36; /* 36 packets per ISOC message */ 1076 1088 1077 - sd->brightness = BRIGHTNESS_DEF; 1078 - sd->gain = GAIN_DEF; 1079 1089 if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) { 1080 - sd->exposure = COARSE_EXPOSURE_DEF; 1081 - gspca_dev->ctrl_dis |= (1 << EXPOSURE_IDX); 1082 - } else { 1083 - sd->exposure = EXPOSURE_DEF; 1084 - gspca_dev->ctrl_dis |= (1 << COARSE_EXPOSURE_IDX); 1090 + sd->ctrls[EXPOSURE].min = COARSE_EXPOSURE_MIN; 1091 + sd->ctrls[EXPOSURE].max = COARSE_EXPOSURE_MAX; 1092 + sd->ctrls[EXPOSURE].def = COARSE_EXPOSURE_DEF; 1085 1093 } 1086 - if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX)) 1087 - sd->autogain = 0; /* Disable do_autogain callback */ 1088 - else 1089 - sd->autogain = AUTOGAIN_DEF; 1090 - sd->freq = FREQ_DEF; 1091 1094 1092 1095 return 0; 1093 1096 } ··· 1377 1398 } 1378 1399 } 1379 1400 1380 - static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 1381 - { 1382 - struct sd *sd = (struct sd *) gspca_dev; 1383 - 1384 - sd->brightness = val; 1385 - if (gspca_dev->streaming) 1386 - setbrightness(gspca_dev); 1387 - return 0; 1388 - } 1389 - 1390 - static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) 1391 - { 1392 - struct sd *sd = (struct sd *) gspca_dev; 1393 - 1394 - *val = sd->brightness; 1395 - return 0; 1396 - } 1397 - 1398 - static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) 1399 - { 1400 - struct sd *sd = (struct sd *) gspca_dev; 1401 - 1402 - sd->gain = val; 1403 - if (gspca_dev->streaming) 1404 - setgain(gspca_dev); 1405 - return 0; 1406 - } 1407 - 1408 - static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) 1409 - { 1410 - struct sd *sd = (struct sd *) gspca_dev; 1411 - 1412 - *val = sd->gain; 1413 - return 0; 1414 - } 1415 - 1416 - static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val) 1417 - { 1418 - struct sd *sd = (struct sd *) gspca_dev; 1419 - 1420 - sd->exposure = val; 1421 - if (gspca_dev->streaming) 1422 - setexposure(gspca_dev); 1423 - return 0; 1424 - } 1425 - 1426 - static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val) 1427 - { 1428 - struct sd *sd = (struct sd *) gspca_dev; 1429 - 1430 - *val = sd->exposure; 1431 - return 0; 1432 - } 1433 - 1434 1401 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) 1435 1402 { 1436 1403 struct sd *sd = (struct sd *) gspca_dev; 1437 1404 1438 - sd->autogain = val; 1405 + sd->ctrls[AUTOGAIN].val = val; 1439 1406 sd->exp_too_high_cnt = 0; 1440 1407 sd->exp_too_low_cnt = 0; 1441 1408 ··· 1389 1464 we are on a valid point of the autogain gain / 1390 1465 exposure knee graph, and give this change time to 1391 1466 take effect before doing autogain. */ 1392 - if (sd->autogain && !(sensor_data[sd->sensor].flags & F_COARSE_EXPO)) { 1393 - sd->exposure = EXPOSURE_DEF; 1394 - sd->gain = GAIN_DEF; 1467 + if (sd->ctrls[AUTOGAIN].val 1468 + && !(sensor_data[sd->sensor].flags & F_COARSE_EXPO)) { 1469 + sd->ctrls[EXPOSURE].val = sd->ctrls[EXPOSURE].def; 1470 + sd->ctrls[GAIN].val = sd->ctrls[GAIN].def; 1395 1471 if (gspca_dev->streaming) { 1396 1472 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; 1397 1473 setexposure(gspca_dev); ··· 1400 1474 } 1401 1475 } 1402 1476 1403 - return 0; 1404 - } 1405 - 1406 - static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) 1407 - { 1408 - struct sd *sd = (struct sd *) gspca_dev; 1409 - 1410 - *val = sd->autogain; 1411 - return 0; 1412 - } 1413 - 1414 - static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) 1415 - { 1416 - struct sd *sd = (struct sd *) gspca_dev; 1417 - 1418 - sd->freq = val; 1419 - if (gspca_dev->streaming) 1420 - setfreq(gspca_dev); 1421 - return 0; 1422 - } 1423 - 1424 - static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) 1425 - { 1426 - struct sd *sd = (struct sd *) gspca_dev; 1427 - 1428 - *val = sd->freq; 1429 1477 return 0; 1430 1478 } 1431 1479