0001
0002
0003
0004
0005
0006
0007
0008 #define MODULE_NAME "jl2005bcd"
0009
0010 #include <linux/workqueue.h>
0011 #include <linux/slab.h>
0012 #include "gspca.h"
0013
0014
0015 MODULE_AUTHOR("Theodore Kilgore <kilgota@auburn.edu>");
0016 MODULE_DESCRIPTION("JL2005B/C/D USB Camera Driver");
0017 MODULE_LICENSE("GPL");
0018
0019
0020 #define JL2005C_CMD_TIMEOUT 500
0021 #define JL2005C_DATA_TIMEOUT 1000
0022
0023
0024 #define JL2005C_MAX_TRANSFER 0x200
0025 #define FRAME_HEADER_LEN 16
0026
0027
0028
0029 struct sd {
0030 struct gspca_dev gspca_dev;
0031 unsigned char firmware_id[6];
0032 const struct v4l2_pix_format *cap_mode;
0033
0034 struct work_struct work_struct;
0035 u8 frame_brightness;
0036 int block_size;
0037 int vga;
0038 };
0039
0040
0041
0042 static const struct v4l2_pix_format cif_mode[] = {
0043 {176, 144, V4L2_PIX_FMT_JL2005BCD, V4L2_FIELD_NONE,
0044 .bytesperline = 176,
0045 .sizeimage = 176 * 144,
0046 .colorspace = V4L2_COLORSPACE_SRGB,
0047 .priv = 0},
0048 {352, 288, V4L2_PIX_FMT_JL2005BCD, V4L2_FIELD_NONE,
0049 .bytesperline = 352,
0050 .sizeimage = 352 * 288,
0051 .colorspace = V4L2_COLORSPACE_SRGB,
0052 .priv = 0},
0053 };
0054
0055 static const struct v4l2_pix_format vga_mode[] = {
0056 {320, 240, V4L2_PIX_FMT_JL2005BCD, V4L2_FIELD_NONE,
0057 .bytesperline = 320,
0058 .sizeimage = 320 * 240,
0059 .colorspace = V4L2_COLORSPACE_SRGB,
0060 .priv = 0},
0061 {640, 480, V4L2_PIX_FMT_JL2005BCD, V4L2_FIELD_NONE,
0062 .bytesperline = 640,
0063 .sizeimage = 640 * 480,
0064 .colorspace = V4L2_COLORSPACE_SRGB,
0065 .priv = 0},
0066 };
0067
0068
0069
0070
0071
0072
0073
0074 static int jl2005c_write2(struct gspca_dev *gspca_dev, unsigned char *command)
0075 {
0076 int retval;
0077
0078 memcpy(gspca_dev->usb_buf, command, 2);
0079 retval = usb_bulk_msg(gspca_dev->dev,
0080 usb_sndbulkpipe(gspca_dev->dev, 3),
0081 gspca_dev->usb_buf, 2, NULL, 500);
0082 if (retval < 0)
0083 pr_err("command write [%02x] error %d\n",
0084 gspca_dev->usb_buf[0], retval);
0085 return retval;
0086 }
0087
0088
0089 static int jl2005c_read1(struct gspca_dev *gspca_dev)
0090 {
0091 int retval;
0092
0093 retval = usb_bulk_msg(gspca_dev->dev,
0094 usb_rcvbulkpipe(gspca_dev->dev, 0x84),
0095 gspca_dev->usb_buf, 1, NULL, 500);
0096 if (retval < 0)
0097 pr_err("read command [0x%02x] error %d\n",
0098 gspca_dev->usb_buf[0], retval);
0099 return retval;
0100 }
0101
0102
0103 static int jl2005c_read_reg(struct gspca_dev *gspca_dev, unsigned char reg)
0104 {
0105 int retval;
0106
0107 static u8 instruction[2] = {0x95, 0x00};
0108
0109 instruction[1] = reg;
0110
0111 retval = jl2005c_write2(gspca_dev, instruction);
0112 if (retval < 0)
0113 return retval;
0114 retval = jl2005c_read1(gspca_dev);
0115
0116 return retval;
0117 }
0118
0119 static int jl2005c_start_new_frame(struct gspca_dev *gspca_dev)
0120 {
0121 int i;
0122 int retval;
0123 int frame_brightness = 0;
0124
0125 static u8 instruction[2] = {0x7f, 0x01};
0126
0127 retval = jl2005c_write2(gspca_dev, instruction);
0128 if (retval < 0)
0129 return retval;
0130
0131 i = 0;
0132 while (i < 20 && !frame_brightness) {
0133
0134 retval = jl2005c_read_reg(gspca_dev, 0x7e);
0135 if (retval < 0)
0136 return retval;
0137 frame_brightness = gspca_dev->usb_buf[0];
0138 retval = jl2005c_read_reg(gspca_dev, 0x7d);
0139 if (retval < 0)
0140 return retval;
0141 i++;
0142 }
0143 gspca_dbg(gspca_dev, D_FRAM, "frame_brightness is 0x%02x\n",
0144 gspca_dev->usb_buf[0]);
0145 return retval;
0146 }
0147
0148 static int jl2005c_write_reg(struct gspca_dev *gspca_dev, unsigned char reg,
0149 unsigned char value)
0150 {
0151 int retval;
0152 u8 instruction[2];
0153
0154 instruction[0] = reg;
0155 instruction[1] = value;
0156
0157 retval = jl2005c_write2(gspca_dev, instruction);
0158 if (retval < 0)
0159 return retval;
0160
0161 return retval;
0162 }
0163
0164 static int jl2005c_get_firmware_id(struct gspca_dev *gspca_dev)
0165 {
0166 struct sd *sd = (struct sd *)gspca_dev;
0167 int i = 0;
0168 int retval;
0169 static const unsigned char regs_to_read[] = {
0170 0x57, 0x02, 0x03, 0x5d, 0x5e, 0x5f
0171 };
0172
0173 gspca_dbg(gspca_dev, D_PROBE, "Running jl2005c_get_firmware_id\n");
0174
0175 retval = jl2005c_read_reg(gspca_dev, regs_to_read[0]);
0176 gspca_dbg(gspca_dev, D_PROBE, "response is %02x\n",
0177 gspca_dev->usb_buf[0]);
0178 if (retval < 0)
0179 return retval;
0180
0181 for (i = 0; i < 6; i++) {
0182 retval = jl2005c_read_reg(gspca_dev, regs_to_read[i]);
0183 if (retval < 0)
0184 return retval;
0185 sd->firmware_id[i] = gspca_dev->usb_buf[0];
0186 }
0187 gspca_dbg(gspca_dev, D_PROBE, "firmware ID is %02x%02x%02x%02x%02x%02x\n",
0188 sd->firmware_id[0],
0189 sd->firmware_id[1],
0190 sd->firmware_id[2],
0191 sd->firmware_id[3],
0192 sd->firmware_id[4],
0193 sd->firmware_id[5]);
0194 return 0;
0195 }
0196
0197 static int jl2005c_stream_start_vga_lg
0198 (struct gspca_dev *gspca_dev)
0199 {
0200 int i;
0201 int retval = -1;
0202 static u8 instruction[][2] = {
0203 {0x05, 0x00},
0204 {0x7c, 0x00},
0205 {0x7d, 0x18},
0206 {0x02, 0x00},
0207 {0x01, 0x00},
0208 {0x04, 0x52},
0209 };
0210
0211 for (i = 0; i < ARRAY_SIZE(instruction); i++) {
0212 msleep(60);
0213 retval = jl2005c_write2(gspca_dev, instruction[i]);
0214 if (retval < 0)
0215 return retval;
0216 }
0217 msleep(60);
0218 return retval;
0219 }
0220
0221 static int jl2005c_stream_start_vga_small(struct gspca_dev *gspca_dev)
0222 {
0223 int i;
0224 int retval = -1;
0225 static u8 instruction[][2] = {
0226 {0x06, 0x00},
0227 {0x7c, 0x00},
0228 {0x7d, 0x1a},
0229 {0x02, 0x00},
0230 {0x01, 0x00},
0231 {0x04, 0x52},
0232 };
0233
0234 for (i = 0; i < ARRAY_SIZE(instruction); i++) {
0235 msleep(60);
0236 retval = jl2005c_write2(gspca_dev, instruction[i]);
0237 if (retval < 0)
0238 return retval;
0239 }
0240 msleep(60);
0241 return retval;
0242 }
0243
0244 static int jl2005c_stream_start_cif_lg(struct gspca_dev *gspca_dev)
0245 {
0246 int i;
0247 int retval = -1;
0248 static u8 instruction[][2] = {
0249 {0x05, 0x00},
0250 {0x7c, 0x00},
0251 {0x7d, 0x30},
0252 {0x02, 0x00},
0253 {0x01, 0x00},
0254 {0x04, 0x42},
0255 };
0256
0257 for (i = 0; i < ARRAY_SIZE(instruction); i++) {
0258 msleep(60);
0259 retval = jl2005c_write2(gspca_dev, instruction[i]);
0260 if (retval < 0)
0261 return retval;
0262 }
0263 msleep(60);
0264 return retval;
0265 }
0266
0267 static int jl2005c_stream_start_cif_small(struct gspca_dev *gspca_dev)
0268 {
0269 int i;
0270 int retval = -1;
0271 static u8 instruction[][2] = {
0272 {0x06, 0x00},
0273 {0x7c, 0x00},
0274 {0x7d, 0x32},
0275 {0x02, 0x00},
0276 {0x01, 0x00},
0277 {0x04, 0x42},
0278 };
0279
0280 for (i = 0; i < ARRAY_SIZE(instruction); i++) {
0281 msleep(60);
0282 retval = jl2005c_write2(gspca_dev, instruction[i]);
0283 if (retval < 0)
0284 return retval;
0285 }
0286 msleep(60);
0287 return retval;
0288 }
0289
0290
0291 static int jl2005c_stop(struct gspca_dev *gspca_dev)
0292 {
0293 return jl2005c_write_reg(gspca_dev, 0x07, 0x00);
0294 }
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304 static void jl2005c_dostream(struct work_struct *work)
0305 {
0306 struct sd *dev = container_of(work, struct sd, work_struct);
0307 struct gspca_dev *gspca_dev = &dev->gspca_dev;
0308 int bytes_left = 0;
0309 int data_len;
0310 int header_read = 0;
0311 unsigned char header_sig[2] = {0x4a, 0x4c};
0312 int act_len;
0313 int packet_type;
0314 int ret;
0315 u8 *buffer;
0316
0317 buffer = kmalloc(JL2005C_MAX_TRANSFER, GFP_KERNEL);
0318 if (!buffer) {
0319 pr_err("Couldn't allocate USB buffer\n");
0320 goto quit_stream;
0321 }
0322
0323 while (gspca_dev->present && gspca_dev->streaming) {
0324 #ifdef CONFIG_PM
0325 if (gspca_dev->frozen)
0326 break;
0327 #endif
0328
0329 if (!header_read) {
0330 mutex_lock(&gspca_dev->usb_lock);
0331 ret = jl2005c_start_new_frame(gspca_dev);
0332 mutex_unlock(&gspca_dev->usb_lock);
0333 if (ret < 0)
0334 goto quit_stream;
0335 ret = usb_bulk_msg(gspca_dev->dev,
0336 usb_rcvbulkpipe(gspca_dev->dev, 0x82),
0337 buffer, JL2005C_MAX_TRANSFER, &act_len,
0338 JL2005C_DATA_TIMEOUT);
0339 gspca_dbg(gspca_dev, D_PACK,
0340 "Got %d bytes out of %d for header\n",
0341 act_len, JL2005C_MAX_TRANSFER);
0342 if (ret < 0 || act_len < JL2005C_MAX_TRANSFER)
0343 goto quit_stream;
0344
0345 if (memcmp(header_sig, buffer, 2) != 0) {
0346 pr_err("First block is not the first block\n");
0347 goto quit_stream;
0348 }
0349
0350
0351 bytes_left = buffer[0x07] * dev->block_size - act_len;
0352 gspca_dbg(gspca_dev, D_PACK, "bytes_left = 0x%x\n",
0353 bytes_left);
0354
0355 packet_type = FIRST_PACKET;
0356 gspca_frame_add(gspca_dev, packet_type,
0357 buffer, act_len);
0358 header_read = 1;
0359 }
0360 while (bytes_left > 0 && gspca_dev->present) {
0361 data_len = bytes_left > JL2005C_MAX_TRANSFER ?
0362 JL2005C_MAX_TRANSFER : bytes_left;
0363 ret = usb_bulk_msg(gspca_dev->dev,
0364 usb_rcvbulkpipe(gspca_dev->dev, 0x82),
0365 buffer, data_len, &act_len,
0366 JL2005C_DATA_TIMEOUT);
0367 if (ret < 0 || act_len < data_len)
0368 goto quit_stream;
0369 gspca_dbg(gspca_dev, D_PACK,
0370 "Got %d bytes out of %d for frame\n",
0371 data_len, bytes_left);
0372 bytes_left -= data_len;
0373 if (bytes_left == 0) {
0374 packet_type = LAST_PACKET;
0375 header_read = 0;
0376 } else
0377 packet_type = INTER_PACKET;
0378 gspca_frame_add(gspca_dev, packet_type,
0379 buffer, data_len);
0380 }
0381 }
0382 quit_stream:
0383 if (gspca_dev->present) {
0384 mutex_lock(&gspca_dev->usb_lock);
0385 jl2005c_stop(gspca_dev);
0386 mutex_unlock(&gspca_dev->usb_lock);
0387 }
0388 kfree(buffer);
0389 }
0390
0391
0392
0393
0394
0395 static int sd_config(struct gspca_dev *gspca_dev,
0396 const struct usb_device_id *id)
0397 {
0398 struct cam *cam;
0399 struct sd *sd = (struct sd *) gspca_dev;
0400
0401 cam = &gspca_dev->cam;
0402
0403 cam->bulk_size = 64;
0404 cam->bulk = 1;
0405
0406 jl2005c_get_firmware_id(gspca_dev);
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419 if ((sd->firmware_id[0] & 0xf0) == 0x40) {
0420 cam->cam_mode = cif_mode;
0421 cam->nmodes = ARRAY_SIZE(cif_mode);
0422 sd->block_size = 0x80;
0423 } else {
0424 cam->cam_mode = vga_mode;
0425 cam->nmodes = ARRAY_SIZE(vga_mode);
0426 sd->block_size = 0x200;
0427 }
0428
0429 INIT_WORK(&sd->work_struct, jl2005c_dostream);
0430
0431 return 0;
0432 }
0433
0434
0435 static int sd_init(struct gspca_dev *gspca_dev)
0436 {
0437 return 0;
0438 }
0439
0440 static int sd_start(struct gspca_dev *gspca_dev)
0441 {
0442
0443 struct sd *sd = (struct sd *) gspca_dev;
0444 sd->cap_mode = gspca_dev->cam.cam_mode;
0445
0446 switch (gspca_dev->pixfmt.width) {
0447 case 640:
0448 gspca_dbg(gspca_dev, D_STREAM, "Start streaming at vga resolution\n");
0449 jl2005c_stream_start_vga_lg(gspca_dev);
0450 break;
0451 case 320:
0452 gspca_dbg(gspca_dev, D_STREAM, "Start streaming at qvga resolution\n");
0453 jl2005c_stream_start_vga_small(gspca_dev);
0454 break;
0455 case 352:
0456 gspca_dbg(gspca_dev, D_STREAM, "Start streaming at cif resolution\n");
0457 jl2005c_stream_start_cif_lg(gspca_dev);
0458 break;
0459 case 176:
0460 gspca_dbg(gspca_dev, D_STREAM, "Start streaming at qcif resolution\n");
0461 jl2005c_stream_start_cif_small(gspca_dev);
0462 break;
0463 default:
0464 pr_err("Unknown resolution specified\n");
0465 return -1;
0466 }
0467
0468 schedule_work(&sd->work_struct);
0469
0470 return 0;
0471 }
0472
0473
0474
0475 static void sd_stop0(struct gspca_dev *gspca_dev)
0476 {
0477 struct sd *dev = (struct sd *) gspca_dev;
0478
0479
0480 mutex_unlock(&gspca_dev->usb_lock);
0481
0482 flush_work(&dev->work_struct);
0483 mutex_lock(&gspca_dev->usb_lock);
0484 }
0485
0486
0487
0488
0489 static const struct sd_desc sd_desc = {
0490 .name = MODULE_NAME,
0491 .config = sd_config,
0492 .init = sd_init,
0493 .start = sd_start,
0494 .stop0 = sd_stop0,
0495 };
0496
0497
0498 static const struct usb_device_id device_table[] = {
0499 {USB_DEVICE(0x0979, 0x0227)},
0500 {}
0501 };
0502 MODULE_DEVICE_TABLE(usb, device_table);
0503
0504
0505 static int sd_probe(struct usb_interface *intf,
0506 const struct usb_device_id *id)
0507 {
0508 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
0509 THIS_MODULE);
0510 }
0511
0512 static struct usb_driver sd_driver = {
0513 .name = MODULE_NAME,
0514 .id_table = device_table,
0515 .probe = sd_probe,
0516 .disconnect = gspca_disconnect,
0517 #ifdef CONFIG_PM
0518 .suspend = gspca_suspend,
0519 .resume = gspca_resume,
0520 .reset_resume = gspca_resume,
0521 #endif
0522 };
0523
0524 module_usb_driver(sd_driver);