diff options
author | Hans de Goede <hdegoede@redhat.com> | 2010-09-05 15:19:19 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-10-20 23:04:45 -0400 |
commit | 659fefa0eb177ae7377206a7a5a59161b0668c58 (patch) | |
tree | c9417db110a05d04f4422e69739d30ceca398fba /drivers/media/video/gspca/xirlink_cit.c | |
parent | 59f90a01e8f1a377213ae6b6f8e8399975c0dc3b (diff) |
V4L/DVB: gspca_xirlink_cit: Add support for camera with a bcd version of 0.01
Add support for camera with a bcd version of 0.01, I've dupped these
Model0 cams.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/gspca/xirlink_cit.c')
-rw-r--r-- | drivers/media/video/gspca/xirlink_cit.c | 414 |
1 files changed, 342 insertions, 72 deletions
diff --git a/drivers/media/video/gspca/xirlink_cit.c b/drivers/media/video/gspca/xirlink_cit.c index 6f2dece1246..3b503b50b82 100644 --- a/drivers/media/video/gspca/xirlink_cit.c +++ b/drivers/media/video/gspca/xirlink_cit.c | |||
@@ -51,11 +51,12 @@ MODULE_PARM_DESC(rca_input, | |||
51 | struct sd { | 51 | struct sd { |
52 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 52 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
53 | u8 model; | 53 | u8 model; |
54 | #define CIT_MODEL1 0 /* The model 1 - 4 nomenclature comes from the old */ | 54 | #define CIT_MODEL0 0 /* bcd version 0.01 cams ie the xvp-500 */ |
55 | #define CIT_MODEL2 1 /* ibmcam driver */ | 55 | #define CIT_MODEL1 1 /* The model 1 - 4 nomenclature comes from the old */ |
56 | #define CIT_MODEL3 2 | 56 | #define CIT_MODEL2 2 /* ibmcam driver */ |
57 | #define CIT_MODEL4 3 | 57 | #define CIT_MODEL3 3 |
58 | #define CIT_IBM_NETCAM_PRO 4 | 58 | #define CIT_MODEL4 4 |
59 | #define CIT_IBM_NETCAM_PRO 5 | ||
59 | u8 input_index; | 60 | u8 input_index; |
60 | u8 stop_on_control_change; | 61 | u8 stop_on_control_change; |
61 | u8 sof_read; | 62 | u8 sof_read; |
@@ -65,6 +66,7 @@ struct sd { | |||
65 | u8 hue; | 66 | u8 hue; |
66 | u8 sharpness; | 67 | u8 sharpness; |
67 | u8 lighting; | 68 | u8 lighting; |
69 | u8 hflip; | ||
68 | }; | 70 | }; |
69 | 71 | ||
70 | /* V4L2 controls supported by the driver */ | 72 | /* V4L2 controls supported by the driver */ |
@@ -78,6 +80,8 @@ static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); | |||
78 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); | 80 | static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); |
79 | static int sd_setlighting(struct gspca_dev *gspca_dev, __s32 val); | 81 | static int sd_setlighting(struct gspca_dev *gspca_dev, __s32 val); |
80 | static int sd_getlighting(struct gspca_dev *gspca_dev, __s32 *val); | 82 | static int sd_getlighting(struct gspca_dev *gspca_dev, __s32 *val); |
83 | static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); | ||
84 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
81 | static void sd_stop0(struct gspca_dev *gspca_dev); | 85 | static void sd_stop0(struct gspca_dev *gspca_dev); |
82 | 86 | ||
83 | static const struct ctrl sd_ctrls[] = { | 87 | static const struct ctrl sd_ctrls[] = { |
@@ -161,12 +165,27 @@ static const struct ctrl sd_ctrls[] = { | |||
161 | .set = sd_setlighting, | 165 | .set = sd_setlighting, |
162 | .get = sd_getlighting, | 166 | .get = sd_getlighting, |
163 | }, | 167 | }, |
168 | #define SD_HFLIP 5 | ||
169 | { | ||
170 | { | ||
171 | .id = V4L2_CID_HFLIP, | ||
172 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
173 | .name = "Mirror", | ||
174 | .minimum = 0, | ||
175 | .maximum = 1, | ||
176 | .step = 1, | ||
177 | #define HFLIP_DEFAULT 0 | ||
178 | .default_value = HFLIP_DEFAULT, | ||
179 | }, | ||
180 | .set = sd_sethflip, | ||
181 | .get = sd_gethflip, | ||
182 | }, | ||
164 | }; | 183 | }; |
165 | 184 | ||
166 | static const struct v4l2_pix_format cif_yuv_mode[] = { | 185 | static const struct v4l2_pix_format cif_yuv_mode[] = { |
167 | {176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, | 186 | {176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, |
168 | .bytesperline = 176, | 187 | .bytesperline = 176, |
169 | .sizeimage = 160 * 144 * 3 / 2, | 188 | .sizeimage = 176 * 144 * 3 / 2, |
170 | .colorspace = V4L2_COLORSPACE_SRGB}, | 189 | .colorspace = V4L2_COLORSPACE_SRGB}, |
171 | {352, 288, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, | 190 | {352, 288, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, |
172 | .bytesperline = 352, | 191 | .bytesperline = 352, |
@@ -189,6 +208,21 @@ static const struct v4l2_pix_format vga_yuv_mode[] = { | |||
189 | .colorspace = V4L2_COLORSPACE_SRGB}, | 208 | .colorspace = V4L2_COLORSPACE_SRGB}, |
190 | }; | 209 | }; |
191 | 210 | ||
211 | static const struct v4l2_pix_format model0_mode[] = { | ||
212 | {160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, | ||
213 | .bytesperline = 160, | ||
214 | .sizeimage = 160 * 120 * 3 / 2, | ||
215 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
216 | {176, 144, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, | ||
217 | .bytesperline = 176, | ||
218 | .sizeimage = 176 * 144 * 3 / 2, | ||
219 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
220 | {320, 240, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, | ||
221 | .bytesperline = 320, | ||
222 | .sizeimage = 320 * 240 * 3 / 2, | ||
223 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
224 | }; | ||
225 | |||
192 | static const struct v4l2_pix_format model2_mode[] = { | 226 | static const struct v4l2_pix_format model2_mode[] = { |
193 | {160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, | 227 | {160, 120, V4L2_PIX_FMT_CIT_YYVYUY, V4L2_FIELD_NONE, |
194 | .bytesperline = 160, | 228 | .bytesperline = 160, |
@@ -957,29 +991,43 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
957 | 991 | ||
958 | cam = &gspca_dev->cam; | 992 | cam = &gspca_dev->cam; |
959 | switch (sd->model) { | 993 | switch (sd->model) { |
994 | case CIT_MODEL0: | ||
995 | cam->cam_mode = model0_mode; | ||
996 | cam->nmodes = ARRAY_SIZE(model0_mode); | ||
997 | cam->reverse_alts = 1; | ||
998 | gspca_dev->ctrl_dis = ~((1 << SD_CONTRAST) | (1 << SD_HFLIP)); | ||
999 | sd->sof_len = 4; | ||
1000 | break; | ||
960 | case CIT_MODEL1: | 1001 | case CIT_MODEL1: |
961 | cam->cam_mode = cif_yuv_mode; | 1002 | cam->cam_mode = cif_yuv_mode; |
962 | cam->nmodes = ARRAY_SIZE(cif_yuv_mode); | 1003 | cam->nmodes = ARRAY_SIZE(cif_yuv_mode); |
963 | gspca_dev->ctrl_dis = (1 << SD_HUE); | 1004 | cam->reverse_alts = 1; |
1005 | gspca_dev->ctrl_dis = (1 << SD_HUE) | (1 << SD_HFLIP); | ||
1006 | sd->sof_len = 4; | ||
964 | break; | 1007 | break; |
965 | case CIT_MODEL2: | 1008 | case CIT_MODEL2: |
966 | cam->cam_mode = model2_mode + 1; /* no 160x120 */ | 1009 | cam->cam_mode = model2_mode + 1; /* no 160x120 */ |
967 | cam->nmodes = 3; | 1010 | cam->nmodes = 3; |
968 | gspca_dev->ctrl_dis = (1 << SD_CONTRAST) | | 1011 | gspca_dev->ctrl_dis = (1 << SD_CONTRAST) | |
969 | (1 << SD_SHARPNESS); | 1012 | (1 << SD_SHARPNESS) | |
1013 | (1 << SD_HFLIP); | ||
970 | break; | 1014 | break; |
971 | case CIT_MODEL3: | 1015 | case CIT_MODEL3: |
972 | cam->cam_mode = vga_yuv_mode; | 1016 | cam->cam_mode = vga_yuv_mode; |
973 | cam->nmodes = ARRAY_SIZE(vga_yuv_mode); | 1017 | cam->nmodes = ARRAY_SIZE(vga_yuv_mode); |
974 | gspca_dev->ctrl_dis = (1 << SD_HUE) | (1 << SD_LIGHTING); | 1018 | gspca_dev->ctrl_dis = (1 << SD_HUE) | |
1019 | (1 << SD_LIGHTING) | | ||
1020 | (1 << SD_HFLIP); | ||
975 | sd->stop_on_control_change = 1; | 1021 | sd->stop_on_control_change = 1; |
1022 | sd->sof_len = 4; | ||
976 | break; | 1023 | break; |
977 | case CIT_MODEL4: | 1024 | case CIT_MODEL4: |
978 | cam->cam_mode = model2_mode; | 1025 | cam->cam_mode = model2_mode; |
979 | cam->nmodes = ARRAY_SIZE(model2_mode); | 1026 | cam->nmodes = ARRAY_SIZE(model2_mode); |
980 | gspca_dev->ctrl_dis = (1 << SD_CONTRAST) | | 1027 | gspca_dev->ctrl_dis = (1 << SD_CONTRAST) | |
981 | (1 << SD_SHARPNESS) | | 1028 | (1 << SD_SHARPNESS) | |
982 | (1 << SD_LIGHTING); | 1029 | (1 << SD_LIGHTING) | |
1030 | (1 << SD_HFLIP); | ||
983 | break; | 1031 | break; |
984 | case CIT_IBM_NETCAM_PRO: | 1032 | case CIT_IBM_NETCAM_PRO: |
985 | cam->cam_mode = vga_yuv_mode; | 1033 | cam->cam_mode = vga_yuv_mode; |
@@ -987,6 +1035,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
987 | cam->input_flags = V4L2_IN_ST_VFLIP; | 1035 | cam->input_flags = V4L2_IN_ST_VFLIP; |
988 | gspca_dev->ctrl_dis = ~(1 << SD_CONTRAST); | 1036 | gspca_dev->ctrl_dis = ~(1 << SD_CONTRAST); |
989 | sd->stop_on_control_change = 1; | 1037 | sd->stop_on_control_change = 1; |
1038 | sd->sof_len = 4; | ||
990 | break; | 1039 | break; |
991 | } | 1040 | } |
992 | 1041 | ||
@@ -995,6 +1044,31 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
995 | sd->hue = HUE_DEFAULT; | 1044 | sd->hue = HUE_DEFAULT; |
996 | sd->sharpness = SHARPNESS_DEFAULT; | 1045 | sd->sharpness = SHARPNESS_DEFAULT; |
997 | sd->lighting = LIGHTING_DEFAULT; | 1046 | sd->lighting = LIGHTING_DEFAULT; |
1047 | sd->hflip = HFLIP_DEFAULT; | ||
1048 | |||
1049 | return 0; | ||
1050 | } | ||
1051 | |||
1052 | static int cit_init_model0(struct gspca_dev *gspca_dev) | ||
1053 | { | ||
1054 | cit_write_reg(gspca_dev, 0x0000, 0x0100); /* turn on led */ | ||
1055 | cit_write_reg(gspca_dev, 0x0001, 0x0112); /* turn on autogain ? */ | ||
1056 | cit_write_reg(gspca_dev, 0x0000, 0x0400); | ||
1057 | cit_write_reg(gspca_dev, 0x0001, 0x0400); | ||
1058 | cit_write_reg(gspca_dev, 0x0000, 0x0420); | ||
1059 | cit_write_reg(gspca_dev, 0x0001, 0x0420); | ||
1060 | cit_write_reg(gspca_dev, 0x000d, 0x0409); | ||
1061 | cit_write_reg(gspca_dev, 0x0002, 0x040a); | ||
1062 | cit_write_reg(gspca_dev, 0x0018, 0x0405); | ||
1063 | cit_write_reg(gspca_dev, 0x0008, 0x0435); | ||
1064 | cit_write_reg(gspca_dev, 0x0026, 0x040b); | ||
1065 | cit_write_reg(gspca_dev, 0x0007, 0x0437); | ||
1066 | cit_write_reg(gspca_dev, 0x0015, 0x042f); | ||
1067 | cit_write_reg(gspca_dev, 0x002b, 0x0439); | ||
1068 | cit_write_reg(gspca_dev, 0x0026, 0x043a); | ||
1069 | cit_write_reg(gspca_dev, 0x0008, 0x0438); | ||
1070 | cit_write_reg(gspca_dev, 0x001e, 0x042b); | ||
1071 | cit_write_reg(gspca_dev, 0x0041, 0x042c); | ||
998 | 1072 | ||
999 | return 0; | 1073 | return 0; |
1000 | } | 1074 | } |
@@ -1197,6 +1271,10 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
1197 | struct sd *sd = (struct sd *) gspca_dev; | 1271 | struct sd *sd = (struct sd *) gspca_dev; |
1198 | 1272 | ||
1199 | switch (sd->model) { | 1273 | switch (sd->model) { |
1274 | case CIT_MODEL0: | ||
1275 | cit_init_model0(gspca_dev); | ||
1276 | sd_stop0(gspca_dev); | ||
1277 | break; | ||
1200 | case CIT_MODEL1: | 1278 | case CIT_MODEL1: |
1201 | case CIT_MODEL2: | 1279 | case CIT_MODEL2: |
1202 | case CIT_MODEL3: | 1280 | case CIT_MODEL3: |
@@ -1216,6 +1294,10 @@ static int cit_set_brightness(struct gspca_dev *gspca_dev) | |||
1216 | int i; | 1294 | int i; |
1217 | 1295 | ||
1218 | switch (sd->model) { | 1296 | switch (sd->model) { |
1297 | case CIT_MODEL0: | ||
1298 | case CIT_IBM_NETCAM_PRO: | ||
1299 | /* No (known) brightness control for these */ | ||
1300 | break; | ||
1219 | case CIT_MODEL1: | 1301 | case CIT_MODEL1: |
1220 | /* Model 1: Brightness range 0 - 63 */ | 1302 | /* Model 1: Brightness range 0 - 63 */ |
1221 | cit_Packet_Format1(gspca_dev, 0x0031, sd->brightness); | 1303 | cit_Packet_Format1(gspca_dev, 0x0031, sd->brightness); |
@@ -1241,9 +1323,6 @@ static int cit_set_brightness(struct gspca_dev *gspca_dev) | |||
1241 | i = 0x04 + sd->brightness * 2794 / 1000; | 1323 | i = 0x04 + sd->brightness * 2794 / 1000; |
1242 | cit_model4_BrightnessPacket(gspca_dev, i); | 1324 | cit_model4_BrightnessPacket(gspca_dev, i); |
1243 | break; | 1325 | break; |
1244 | case CIT_IBM_NETCAM_PRO: | ||
1245 | /* No (known) brightness control for ibm netcam pro */ | ||
1246 | break; | ||
1247 | } | 1326 | } |
1248 | 1327 | ||
1249 | return 0; | 1328 | return 0; |
@@ -1254,6 +1333,26 @@ static int cit_set_contrast(struct gspca_dev *gspca_dev) | |||
1254 | struct sd *sd = (struct sd *) gspca_dev; | 1333 | struct sd *sd = (struct sd *) gspca_dev; |
1255 | 1334 | ||
1256 | switch (sd->model) { | 1335 | switch (sd->model) { |
1336 | case CIT_MODEL0: { | ||
1337 | int i; | ||
1338 | /* gain 0-15, 0-20 -> 0-15 */ | ||
1339 | i = sd->contrast * 1000 / 1333; | ||
1340 | cit_write_reg(gspca_dev, i, 0x0422); | ||
1341 | /* gain 0-31, may not be lower then 0x0422, 0-20 -> 0-31 */ | ||
1342 | i = sd->contrast * 2000 / 1333; | ||
1343 | cit_write_reg(gspca_dev, i, 0x0423); | ||
1344 | /* gain 0-127, may not be lower then 0x0423, 0-20 -> 0-63 */ | ||
1345 | i = sd->contrast * 4000 / 1333; | ||
1346 | cit_write_reg(gspca_dev, i, 0x0424); | ||
1347 | /* gain 0-127, may not be lower then 0x0424, , 0-20 -> 0-127 */ | ||
1348 | i = sd->contrast * 8000 / 1333; | ||
1349 | cit_write_reg(gspca_dev, i, 0x0425); | ||
1350 | break; | ||
1351 | } | ||
1352 | case CIT_MODEL2: | ||
1353 | case CIT_MODEL4: | ||
1354 | /* These models do not have this control. */ | ||
1355 | break; | ||
1257 | case CIT_MODEL1: | 1356 | case CIT_MODEL1: |
1258 | { | 1357 | { |
1259 | /* Scale 0 - 20 to 15 - 0 */ | 1358 | /* Scale 0 - 20 to 15 - 0 */ |
@@ -1264,10 +1363,6 @@ static int cit_set_contrast(struct gspca_dev *gspca_dev) | |||
1264 | } | 1363 | } |
1265 | break; | 1364 | break; |
1266 | } | 1365 | } |
1267 | case CIT_MODEL2: | ||
1268 | case CIT_MODEL4: | ||
1269 | /* Models 2, 4 do not have this control. */ | ||
1270 | break; | ||
1271 | case CIT_MODEL3: | 1366 | case CIT_MODEL3: |
1272 | { /* Preset hardware values */ | 1367 | { /* Preset hardware values */ |
1273 | static const struct { | 1368 | static const struct { |
@@ -1301,8 +1396,10 @@ static int cit_set_hue(struct gspca_dev *gspca_dev) | |||
1301 | struct sd *sd = (struct sd *) gspca_dev; | 1396 | struct sd *sd = (struct sd *) gspca_dev; |
1302 | 1397 | ||
1303 | switch (sd->model) { | 1398 | switch (sd->model) { |
1399 | case CIT_MODEL0: | ||
1304 | case CIT_MODEL1: | 1400 | case CIT_MODEL1: |
1305 | /* No hue control for model1 */ | 1401 | case CIT_IBM_NETCAM_PRO: |
1402 | /* No hue control for these models */ | ||
1306 | break; | 1403 | break; |
1307 | case CIT_MODEL2: | 1404 | case CIT_MODEL2: |
1308 | cit_model2_Packet1(gspca_dev, 0x0024, sd->hue); | 1405 | cit_model2_Packet1(gspca_dev, 0x0024, sd->hue); |
@@ -1342,9 +1439,6 @@ static int cit_set_hue(struct gspca_dev *gspca_dev) | |||
1342 | cit_write_reg(gspca_dev, sd->hue, 0x012d); /* Hue */ | 1439 | cit_write_reg(gspca_dev, sd->hue, 0x012d); /* Hue */ |
1343 | cit_write_reg(gspca_dev, 0xf545, 0x0124); | 1440 | cit_write_reg(gspca_dev, 0xf545, 0x0124); |
1344 | break; | 1441 | break; |
1345 | case CIT_IBM_NETCAM_PRO: | ||
1346 | /* No hue control for ibm netcam pro */ | ||
1347 | break; | ||
1348 | } | 1442 | } |
1349 | return 0; | 1443 | return 0; |
1350 | } | 1444 | } |
@@ -1354,6 +1448,12 @@ static int cit_set_sharpness(struct gspca_dev *gspca_dev) | |||
1354 | struct sd *sd = (struct sd *) gspca_dev; | 1448 | struct sd *sd = (struct sd *) gspca_dev; |
1355 | 1449 | ||
1356 | switch (sd->model) { | 1450 | switch (sd->model) { |
1451 | case CIT_MODEL0: | ||
1452 | case CIT_MODEL2: | ||
1453 | case CIT_MODEL4: | ||
1454 | case CIT_IBM_NETCAM_PRO: | ||
1455 | /* These models do not have this control */ | ||
1456 | break; | ||
1357 | case CIT_MODEL1: { | 1457 | case CIT_MODEL1: { |
1358 | int i; | 1458 | int i; |
1359 | const unsigned short sa[] = { | 1459 | const unsigned short sa[] = { |
@@ -1363,10 +1463,6 @@ static int cit_set_sharpness(struct gspca_dev *gspca_dev) | |||
1363 | cit_PacketFormat2(gspca_dev, 0x0013, sa[sd->sharpness]); | 1463 | cit_PacketFormat2(gspca_dev, 0x0013, sa[sd->sharpness]); |
1364 | break; | 1464 | break; |
1365 | } | 1465 | } |
1366 | case CIT_MODEL2: | ||
1367 | case CIT_MODEL4: | ||
1368 | /* Models 2, 4 do not have this control */ | ||
1369 | break; | ||
1370 | case CIT_MODEL3: | 1466 | case CIT_MODEL3: |
1371 | { /* | 1467 | { /* |
1372 | * "Use a table of magic numbers. | 1468 | * "Use a table of magic numbers. |
@@ -1393,9 +1489,6 @@ static int cit_set_sharpness(struct gspca_dev *gspca_dev) | |||
1393 | cit_model3_Packet1(gspca_dev, 0x0063, sv[sd->sharpness].sv4); | 1489 | cit_model3_Packet1(gspca_dev, 0x0063, sv[sd->sharpness].sv4); |
1394 | break; | 1490 | break; |
1395 | } | 1491 | } |
1396 | case CIT_IBM_NETCAM_PRO: | ||
1397 | /* No sharpness setting on ibm netcamera pro */ | ||
1398 | break; | ||
1399 | } | 1492 | } |
1400 | return 0; | 1493 | return 0; |
1401 | } | 1494 | } |
@@ -1423,12 +1516,33 @@ static void cit_set_lighting(struct gspca_dev *gspca_dev) | |||
1423 | struct sd *sd = (struct sd *) gspca_dev; | 1516 | struct sd *sd = (struct sd *) gspca_dev; |
1424 | 1517 | ||
1425 | switch (sd->model) { | 1518 | switch (sd->model) { |
1519 | case CIT_MODEL0: | ||
1520 | case CIT_MODEL2: | ||
1521 | case CIT_MODEL3: | ||
1522 | case CIT_MODEL4: | ||
1523 | case CIT_IBM_NETCAM_PRO: | ||
1524 | break; | ||
1426 | case CIT_MODEL1: { | 1525 | case CIT_MODEL1: { |
1427 | int i; | 1526 | int i; |
1428 | for (i = 0; i < cit_model1_ntries; i++) | 1527 | for (i = 0; i < cit_model1_ntries; i++) |
1429 | cit_Packet_Format1(gspca_dev, 0x0027, sd->lighting); | 1528 | cit_Packet_Format1(gspca_dev, 0x0027, sd->lighting); |
1430 | break; | 1529 | break; |
1431 | } | 1530 | } |
1531 | } | ||
1532 | } | ||
1533 | |||
1534 | static void cit_set_hflip(struct gspca_dev *gspca_dev) | ||
1535 | { | ||
1536 | struct sd *sd = (struct sd *) gspca_dev; | ||
1537 | |||
1538 | switch (sd->model) { | ||
1539 | case CIT_MODEL0: | ||
1540 | if (sd->hflip) | ||
1541 | cit_write_reg(gspca_dev, 0x0020, 0x0115); | ||
1542 | else | ||
1543 | cit_write_reg(gspca_dev, 0x0040, 0x0115); | ||
1544 | break; | ||
1545 | case CIT_MODEL1: | ||
1432 | case CIT_MODEL2: | 1546 | case CIT_MODEL2: |
1433 | case CIT_MODEL3: | 1547 | case CIT_MODEL3: |
1434 | case CIT_MODEL4: | 1548 | case CIT_MODEL4: |
@@ -1442,6 +1556,7 @@ static int cit_restart_stream(struct gspca_dev *gspca_dev) | |||
1442 | struct sd *sd = (struct sd *) gspca_dev; | 1556 | struct sd *sd = (struct sd *) gspca_dev; |
1443 | 1557 | ||
1444 | switch (sd->model) { | 1558 | switch (sd->model) { |
1559 | case CIT_MODEL0: | ||
1445 | case CIT_MODEL1: | 1560 | case CIT_MODEL1: |
1446 | case CIT_MODEL3: | 1561 | case CIT_MODEL3: |
1447 | case CIT_IBM_NETCAM_PRO: | 1562 | case CIT_IBM_NETCAM_PRO: |
@@ -1463,6 +1578,84 @@ static int cit_restart_stream(struct gspca_dev *gspca_dev) | |||
1463 | return 0; | 1578 | return 0; |
1464 | } | 1579 | } |
1465 | 1580 | ||
1581 | static int cit_get_packet_size(struct gspca_dev *gspca_dev) | ||
1582 | { | ||
1583 | struct usb_host_interface *alt; | ||
1584 | struct usb_interface *intf; | ||
1585 | |||
1586 | intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); | ||
1587 | alt = usb_altnum_to_altsetting(intf, gspca_dev->alt); | ||
1588 | if (!alt) { | ||
1589 | PDEBUG(D_ERR, "Couldn't get altsetting"); | ||
1590 | return -EIO; | ||
1591 | } | ||
1592 | |||
1593 | return le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); | ||
1594 | } | ||
1595 | |||
1596 | static int cit_start_model0(struct gspca_dev *gspca_dev) | ||
1597 | { | ||
1598 | const unsigned short compression = 0; /* 0=none, 7=best frame rate */ | ||
1599 | int clock_div = 7; /* 0=30 1=25 2=20 3=15 4=12 5=7.5 6=6 7=3fps ?? */ | ||
1600 | int fps[8] = { 30, 25, 20, 15, 12, 8, 6, 3 }; | ||
1601 | int packet_size; | ||
1602 | |||
1603 | packet_size = cit_get_packet_size(gspca_dev); | ||
1604 | if (packet_size < 0) | ||
1605 | return packet_size; | ||
1606 | |||
1607 | while (clock_div > 3 && | ||
1608 | 1000 * packet_size > | ||
1609 | gspca_dev->width * gspca_dev->height * | ||
1610 | fps[clock_div - 1] * 3 / 2) | ||
1611 | clock_div--; | ||
1612 | |||
1613 | cit_write_reg(gspca_dev, 0x0000, 0x0100); /* turn on led */ | ||
1614 | cit_write_reg(gspca_dev, 0x0003, 0x0438); | ||
1615 | cit_write_reg(gspca_dev, 0x001e, 0x042b); | ||
1616 | cit_write_reg(gspca_dev, 0x0041, 0x042c); | ||
1617 | cit_write_reg(gspca_dev, 0x0008, 0x0436); | ||
1618 | cit_write_reg(gspca_dev, 0x0024, 0x0403); | ||
1619 | cit_write_reg(gspca_dev, 0x002c, 0x0404); | ||
1620 | cit_write_reg(gspca_dev, 0x0002, 0x0426); | ||
1621 | cit_write_reg(gspca_dev, 0x0014, 0x0427); | ||
1622 | |||
1623 | switch (gspca_dev->width) { | ||
1624 | case 160: /* 160x120 */ | ||
1625 | cit_write_reg(gspca_dev, 0x0004, 0x010b); | ||
1626 | cit_write_reg(gspca_dev, 0x0001, 0x010a); | ||
1627 | cit_write_reg(gspca_dev, 0x0010, 0x0102); | ||
1628 | cit_write_reg(gspca_dev, 0x00a0, 0x0103); | ||
1629 | cit_write_reg(gspca_dev, 0x0000, 0x0104); | ||
1630 | cit_write_reg(gspca_dev, 0x0078, 0x0105); | ||
1631 | break; | ||
1632 | |||
1633 | case 176: /* 176x144 */ | ||
1634 | cit_write_reg(gspca_dev, 0x0006, 0x010b); | ||
1635 | cit_write_reg(gspca_dev, 0x0000, 0x010a); | ||
1636 | cit_write_reg(gspca_dev, 0x0005, 0x0102); | ||
1637 | cit_write_reg(gspca_dev, 0x00b0, 0x0103); | ||
1638 | cit_write_reg(gspca_dev, 0x0000, 0x0104); | ||
1639 | cit_write_reg(gspca_dev, 0x0090, 0x0105); | ||
1640 | break; | ||
1641 | |||
1642 | case 320: /* 320x240 */ | ||
1643 | cit_write_reg(gspca_dev, 0x0008, 0x010b); | ||
1644 | cit_write_reg(gspca_dev, 0x0004, 0x010a); | ||
1645 | cit_write_reg(gspca_dev, 0x0005, 0x0102); | ||
1646 | cit_write_reg(gspca_dev, 0x00a0, 0x0103); | ||
1647 | cit_write_reg(gspca_dev, 0x0010, 0x0104); | ||
1648 | cit_write_reg(gspca_dev, 0x0078, 0x0105); | ||
1649 | break; | ||
1650 | } | ||
1651 | |||
1652 | cit_write_reg(gspca_dev, compression, 0x0109); | ||
1653 | cit_write_reg(gspca_dev, clock_div, 0x0111); | ||
1654 | PDEBUG(D_PROBE, "Using clockdiv: %d", clock_div); | ||
1655 | |||
1656 | return 0; | ||
1657 | } | ||
1658 | |||
1466 | static int cit_start_model1(struct gspca_dev *gspca_dev) | 1659 | static int cit_start_model1(struct gspca_dev *gspca_dev) |
1467 | { | 1660 | { |
1468 | struct sd *sd = (struct sd *) gspca_dev; | 1661 | struct sd *sd = (struct sd *) gspca_dev; |
@@ -1660,8 +1853,6 @@ static int cit_start_model1(struct gspca_dev *gspca_dev) | |||
1660 | cit_write_reg(gspca_dev, 0x01, 0x0100); /* LED On */ | 1853 | cit_write_reg(gspca_dev, 0x01, 0x0100); /* LED On */ |
1661 | cit_write_reg(gspca_dev, clock_div, 0x0111); | 1854 | cit_write_reg(gspca_dev, clock_div, 0x0111); |
1662 | 1855 | ||
1663 | sd->sof_len = 4; | ||
1664 | |||
1665 | return 0; | 1856 | return 0; |
1666 | } | 1857 | } |
1667 | 1858 | ||
@@ -1858,7 +2049,6 @@ static int cit_start_model2(struct gspca_dev *gspca_dev) | |||
1858 | 2049 | ||
1859 | static int cit_start_model3(struct gspca_dev *gspca_dev) | 2050 | static int cit_start_model3(struct gspca_dev *gspca_dev) |
1860 | { | 2051 | { |
1861 | struct sd *sd = (struct sd *) gspca_dev; | ||
1862 | const unsigned short compression = 0; /* 0=none, 7=best frame rate */ | 2052 | const unsigned short compression = 0; /* 0=none, 7=best frame rate */ |
1863 | int i, clock_div = 0; | 2053 | int i, clock_div = 0; |
1864 | 2054 | ||
@@ -2091,8 +2281,6 @@ static int cit_start_model3(struct gspca_dev *gspca_dev) | |||
2091 | } | 2281 | } |
2092 | } | 2282 | } |
2093 | 2283 | ||
2094 | sd->sof_len = 4; | ||
2095 | |||
2096 | return 0; | 2284 | return 0; |
2097 | } | 2285 | } |
2098 | 2286 | ||
@@ -2423,7 +2611,6 @@ static int cit_start_model4(struct gspca_dev *gspca_dev) | |||
2423 | 2611 | ||
2424 | static int cit_start_ibm_netcam_pro(struct gspca_dev *gspca_dev) | 2612 | static int cit_start_ibm_netcam_pro(struct gspca_dev *gspca_dev) |
2425 | { | 2613 | { |
2426 | struct sd *sd = (struct sd *) gspca_dev; | ||
2427 | const unsigned short compression = 0; /* 0=none, 7=best frame rate */ | 2614 | const unsigned short compression = 0; /* 0=none, 7=best frame rate */ |
2428 | int i, clock_div = 0; | 2615 | int i, clock_div = 0; |
2429 | 2616 | ||
@@ -2454,7 +2641,7 @@ static int cit_start_ibm_netcam_pro(struct gspca_dev *gspca_dev) | |||
2454 | cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */ | 2641 | cit_write_reg(gspca_dev, 0x0022, 0x012a); /* Same */ |
2455 | 2642 | ||
2456 | switch (gspca_dev->width) { | 2643 | switch (gspca_dev->width) { |
2457 | case 160: | 2644 | case 160: /* 160x120 */ |
2458 | cit_write_reg(gspca_dev, 0x0024, 0x010b); | 2645 | cit_write_reg(gspca_dev, 0x0024, 0x010b); |
2459 | cit_write_reg(gspca_dev, 0x0089, 0x0119); | 2646 | cit_write_reg(gspca_dev, 0x0089, 0x0119); |
2460 | cit_write_reg(gspca_dev, 0x000a, 0x011b); | 2647 | cit_write_reg(gspca_dev, 0x000a, 0x011b); |
@@ -2466,7 +2653,7 @@ static int cit_start_ibm_netcam_pro(struct gspca_dev *gspca_dev) | |||
2466 | cit_write_reg(gspca_dev, 0x0000, 0x0132); | 2653 | cit_write_reg(gspca_dev, 0x0000, 0x0132); |
2467 | clock_div = 3; | 2654 | clock_div = 3; |
2468 | break; | 2655 | break; |
2469 | case 320: | 2656 | case 320: /* 320x240 */ |
2470 | cit_write_reg(gspca_dev, 0x0028, 0x010b); | 2657 | cit_write_reg(gspca_dev, 0x0028, 0x010b); |
2471 | cit_write_reg(gspca_dev, 0x00d9, 0x0119); | 2658 | cit_write_reg(gspca_dev, 0x00d9, 0x0119); |
2472 | cit_write_reg(gspca_dev, 0x0006, 0x011b); | 2659 | cit_write_reg(gspca_dev, 0x0006, 0x011b); |
@@ -2511,8 +2698,6 @@ static int cit_start_ibm_netcam_pro(struct gspca_dev *gspca_dev) | |||
2511 | } | 2698 | } |
2512 | } | 2699 | } |
2513 | 2700 | ||
2514 | sd->sof_len = 4; | ||
2515 | |||
2516 | return 0; | 2701 | return 0; |
2517 | } | 2702 | } |
2518 | 2703 | ||
@@ -2520,11 +2705,16 @@ static int cit_start_ibm_netcam_pro(struct gspca_dev *gspca_dev) | |||
2520 | static int sd_start(struct gspca_dev *gspca_dev) | 2705 | static int sd_start(struct gspca_dev *gspca_dev) |
2521 | { | 2706 | { |
2522 | struct sd *sd = (struct sd *) gspca_dev; | 2707 | struct sd *sd = (struct sd *) gspca_dev; |
2523 | struct usb_host_interface *alt; | ||
2524 | struct usb_interface *intf; | ||
2525 | int packet_size; | 2708 | int packet_size; |
2526 | 2709 | ||
2710 | packet_size = cit_get_packet_size(gspca_dev); | ||
2711 | if (packet_size < 0) | ||
2712 | return packet_size; | ||
2713 | |||
2527 | switch (sd->model) { | 2714 | switch (sd->model) { |
2715 | case CIT_MODEL0: | ||
2716 | cit_start_model0(gspca_dev); | ||
2717 | break; | ||
2528 | case CIT_MODEL1: | 2718 | case CIT_MODEL1: |
2529 | cit_start_model1(gspca_dev); | 2719 | cit_start_model1(gspca_dev); |
2530 | break; | 2720 | break; |
@@ -2547,18 +2737,9 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
2547 | cit_set_hue(gspca_dev); | 2737 | cit_set_hue(gspca_dev); |
2548 | cit_set_sharpness(gspca_dev); | 2738 | cit_set_sharpness(gspca_dev); |
2549 | cit_set_lighting(gspca_dev); | 2739 | cit_set_lighting(gspca_dev); |
2740 | cit_set_hflip(gspca_dev); | ||
2550 | 2741 | ||
2551 | /* Program max isoc packet size, one day we should use this to | 2742 | /* Program max isoc packet size */ |
2552 | allow us to work together with other isoc devices on the same | ||
2553 | root hub. */ | ||
2554 | intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); | ||
2555 | alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); | ||
2556 | if (!alt) { | ||
2557 | PDEBUG(D_ERR, "Couldn't get altsetting"); | ||
2558 | return -EIO; | ||
2559 | } | ||
2560 | |||
2561 | packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); | ||
2562 | cit_write_reg(gspca_dev, packet_size >> 8, 0x0106); | 2743 | cit_write_reg(gspca_dev, packet_size >> 8, 0x0106); |
2563 | cit_write_reg(gspca_dev, packet_size & 0xff, 0x0107); | 2744 | cit_write_reg(gspca_dev, packet_size & 0xff, 0x0107); |
2564 | 2745 | ||
@@ -2582,6 +2763,13 @@ static void sd_stop0(struct gspca_dev *gspca_dev) | |||
2582 | return; | 2763 | return; |
2583 | 2764 | ||
2584 | switch (sd->model) { | 2765 | switch (sd->model) { |
2766 | case CIT_MODEL0: | ||
2767 | /* HDG windows does this, but it causes the cams autogain to | ||
2768 | restart from a gain of 0, which does not look good when | ||
2769 | changing resolutions. */ | ||
2770 | /* cit_write_reg(gspca_dev, 0x0000, 0x0112); */ | ||
2771 | cit_write_reg(gspca_dev, 0x00c0, 0x0100); /* LED Off */ | ||
2772 | break; | ||
2585 | case CIT_MODEL1: | 2773 | case CIT_MODEL1: |
2586 | cit_send_FF_04_02(gspca_dev); | 2774 | cit_send_FF_04_02(gspca_dev); |
2587 | cit_read_reg(gspca_dev, 0x0100); | 2775 | cit_read_reg(gspca_dev, 0x0100); |
@@ -2635,21 +2823,47 @@ static void sd_stop0(struct gspca_dev *gspca_dev) | |||
2635 | static u8 *cit_find_sof(struct gspca_dev *gspca_dev, u8 *data, int len) | 2823 | static u8 *cit_find_sof(struct gspca_dev *gspca_dev, u8 *data, int len) |
2636 | { | 2824 | { |
2637 | struct sd *sd = (struct sd *) gspca_dev; | 2825 | struct sd *sd = (struct sd *) gspca_dev; |
2638 | u8 byte3; | 2826 | u8 byte3 = 0, byte4 = 0; |
2639 | int i; | 2827 | int i; |
2640 | 2828 | ||
2641 | switch (sd->model) { | 2829 | switch (sd->model) { |
2830 | case CIT_MODEL0: | ||
2642 | case CIT_MODEL1: | 2831 | case CIT_MODEL1: |
2643 | case CIT_MODEL3: | 2832 | case CIT_MODEL3: |
2644 | case CIT_IBM_NETCAM_PRO: | 2833 | case CIT_IBM_NETCAM_PRO: |
2645 | if (sd->model == CIT_MODEL1) | 2834 | switch (gspca_dev->width) { |
2646 | byte3 = 0x00; | 2835 | case 160: /* 160x120 */ |
2647 | else if (gspca_dev->width == 640) | 2836 | byte3 = 0x02; |
2648 | byte3 = 0x03; | 2837 | byte4 = 0x0a; |
2649 | else | 2838 | break; |
2839 | case 176: /* 176x144 */ | ||
2840 | byte3 = 0x02; | ||
2841 | byte4 = 0x0e; | ||
2842 | break; | ||
2843 | case 320: /* 320x240 */ | ||
2650 | byte3 = 0x02; | 2844 | byte3 = 0x02; |
2845 | byte4 = 0x08; | ||
2846 | break; | ||
2847 | case 352: /* 352x288 */ | ||
2848 | byte3 = 0x02; | ||
2849 | byte4 = 0x00; | ||
2850 | break; | ||
2851 | case 640: | ||
2852 | byte3 = 0x03; | ||
2853 | byte4 = 0x08; | ||
2854 | break; | ||
2855 | } | ||
2856 | |||
2857 | /* These have a different byte3 */ | ||
2858 | if (sd->model <= CIT_MODEL1) | ||
2859 | byte3 = 0x00; | ||
2651 | 2860 | ||
2652 | for (i = 0; i < len; i++) { | 2861 | for (i = 0; i < len; i++) { |
2862 | /* For this model the SOF always starts at offset 0 | ||
2863 | so no need to search the entire frame */ | ||
2864 | if (sd->model == CIT_MODEL0 && sd->sof_read != i) | ||
2865 | break; | ||
2866 | |||
2653 | switch (sd->sof_read) { | 2867 | switch (sd->sof_read) { |
2654 | case 0: | 2868 | case 0: |
2655 | if (data[i] == 0x00) | 2869 | if (data[i] == 0x00) |
@@ -2658,22 +2872,30 @@ static u8 *cit_find_sof(struct gspca_dev *gspca_dev, u8 *data, int len) | |||
2658 | case 1: | 2872 | case 1: |
2659 | if (data[i] == 0xff) | 2873 | if (data[i] == 0xff) |
2660 | sd->sof_read++; | 2874 | sd->sof_read++; |
2875 | else if (data[i] == 0x00) | ||
2876 | sd->sof_read = 1; | ||
2661 | else | 2877 | else |
2662 | sd->sof_read = 0; | 2878 | sd->sof_read = 0; |
2663 | break; | 2879 | break; |
2664 | case 2: | 2880 | case 2: |
2665 | sd->sof_read = 0; | 2881 | if (data[i] == byte3) |
2666 | if (data[i] == byte3) { | 2882 | sd->sof_read++; |
2667 | if (i >= 4) | 2883 | else if (data[i] == 0x00) |
2668 | PDEBUG(D_FRAM, | 2884 | sd->sof_read = 1; |
2669 | "header found at offset: %d: %02x %02x 00 ff %02x %02x\n", | 2885 | else |
2670 | i - 2, | 2886 | sd->sof_read = 0; |
2671 | data[i - 4], | 2887 | break; |
2672 | data[i - 3], | 2888 | case 3: |
2673 | data[i], | 2889 | if (data[i] == byte4) { |
2674 | data[i + 1]); | 2890 | sd->sof_read = 0; |
2675 | return data + i + (sd->sof_len - 2); | 2891 | return data + i + (sd->sof_len - 3); |
2676 | } | 2892 | } |
2893 | if (byte3 == 0x00 && data[i] == 0xff) | ||
2894 | sd->sof_read = 2; | ||
2895 | else if (data[i] == 0x00) | ||
2896 | sd->sof_read = 1; | ||
2897 | else | ||
2898 | sd->sof_read = 0; | ||
2677 | break; | 2899 | break; |
2678 | } | 2900 | } |
2679 | } | 2901 | } |
@@ -2693,13 +2915,21 @@ static u8 *cit_find_sof(struct gspca_dev *gspca_dev, u8 *data, int len) | |||
2693 | if (data[i] == 0xff) { | 2915 | if (data[i] == 0xff) { |
2694 | if (i >= 4) | 2916 | if (i >= 4) |
2695 | PDEBUG(D_FRAM, | 2917 | PDEBUG(D_FRAM, |
2696 | "header found at offset: %d: %02x %02x 00 ff %02x %02x\n", | 2918 | "header found at offset: %d: %02x %02x 00 %02x %02x %02x\n", |
2697 | i - 2, | 2919 | i - 1, |
2698 | data[i - 4], | 2920 | data[i - 4], |
2699 | data[i - 3], | 2921 | data[i - 3], |
2700 | data[i], | 2922 | data[i], |
2701 | data[i + 1]); | 2923 | data[i + 1], |
2702 | return data + i + (sd->sof_len - 2); | 2924 | data[i + 2]); |
2925 | else | ||
2926 | PDEBUG(D_FRAM, | ||
2927 | "header found at offset: %d: 00 %02x %02x %02x\n", | ||
2928 | i - 1, | ||
2929 | data[i], | ||
2930 | data[i + 1], | ||
2931 | data[i + 2]); | ||
2932 | return data + i + (sd->sof_len - 1); | ||
2703 | } | 2933 | } |
2704 | break; | 2934 | break; |
2705 | } | 2935 | } |
@@ -2857,6 +3087,30 @@ static int sd_getlighting(struct gspca_dev *gspca_dev, __s32 *val) | |||
2857 | return 0; | 3087 | return 0; |
2858 | } | 3088 | } |
2859 | 3089 | ||
3090 | static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val) | ||
3091 | { | ||
3092 | struct sd *sd = (struct sd *) gspca_dev; | ||
3093 | |||
3094 | sd->hflip = val; | ||
3095 | if (gspca_dev->streaming) { | ||
3096 | if (sd->stop_on_control_change) | ||
3097 | sd_stopN(gspca_dev); | ||
3098 | cit_set_hflip(gspca_dev); | ||
3099 | if (sd->stop_on_control_change) | ||
3100 | cit_restart_stream(gspca_dev); | ||
3101 | } | ||
3102 | return 0; | ||
3103 | } | ||
3104 | |||
3105 | static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
3106 | { | ||
3107 | struct sd *sd = (struct sd *) gspca_dev; | ||
3108 | |||
3109 | *val = sd->hflip; | ||
3110 | |||
3111 | return 0; | ||
3112 | } | ||
3113 | |||
2860 | 3114 | ||
2861 | /* sub-driver description */ | 3115 | /* sub-driver description */ |
2862 | static const struct sd_desc sd_desc = { | 3116 | static const struct sd_desc sd_desc = { |
@@ -2873,6 +3127,7 @@ static const struct sd_desc sd_desc = { | |||
2873 | 3127 | ||
2874 | /* -- module initialisation -- */ | 3128 | /* -- module initialisation -- */ |
2875 | static const __devinitdata struct usb_device_id device_table[] = { | 3129 | static const __devinitdata struct usb_device_id device_table[] = { |
3130 | { USB_DEVICE_VER(0x0545, 0x8080, 0x0001, 0x0001), .driver_info = CIT_MODEL0 }, | ||
2876 | { USB_DEVICE_VER(0x0545, 0x8080, 0x0002, 0x0002), .driver_info = CIT_MODEL1 }, | 3131 | { USB_DEVICE_VER(0x0545, 0x8080, 0x0002, 0x0002), .driver_info = CIT_MODEL1 }, |
2877 | { USB_DEVICE_VER(0x0545, 0x8080, 0x030a, 0x030a), .driver_info = CIT_MODEL2 }, | 3132 | { USB_DEVICE_VER(0x0545, 0x8080, 0x030a, 0x030a), .driver_info = CIT_MODEL2 }, |
2878 | { USB_DEVICE_VER(0x0545, 0x8080, 0x0301, 0x0301), .driver_info = CIT_MODEL3 }, | 3133 | { USB_DEVICE_VER(0x0545, 0x8080, 0x0301, 0x0301), .driver_info = CIT_MODEL3 }, |
@@ -2887,6 +3142,21 @@ MODULE_DEVICE_TABLE(usb, device_table); | |||
2887 | static int sd_probe(struct usb_interface *intf, | 3142 | static int sd_probe(struct usb_interface *intf, |
2888 | const struct usb_device_id *id) | 3143 | const struct usb_device_id *id) |
2889 | { | 3144 | { |
3145 | switch (id->driver_info) { | ||
3146 | case CIT_MODEL0: | ||
3147 | case CIT_MODEL1: | ||
3148 | if (intf->cur_altsetting->desc.bInterfaceNumber != 2) | ||
3149 | return -ENODEV; | ||
3150 | break; | ||
3151 | case CIT_MODEL2: | ||
3152 | case CIT_MODEL3: | ||
3153 | case CIT_MODEL4: | ||
3154 | case CIT_IBM_NETCAM_PRO: | ||
3155 | if (intf->cur_altsetting->desc.bInterfaceNumber != 0) | ||
3156 | return -ENODEV; | ||
3157 | break; | ||
3158 | } | ||
3159 | |||
2890 | return gspca_dev_probe2(intf, id, &sd_desc, sizeof(struct sd), | 3160 | return gspca_dev_probe2(intf, id, &sd_desc, sizeof(struct sd), |
2891 | THIS_MODULE); | 3161 | THIS_MODULE); |
2892 | } | 3162 | } |