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

[media] gspca - jeilinj: Add SPORTSCAM_DV15 camera support

Signed-off-by: Patrice CHOTARD <patricechotard@free.fr>
Signed-off-by: Jean-François Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

authored by

Patrice Chotard and committed by
Mauro Carvalho Chehab
713b466f 6f8efcfb

+68 -31
+1
Documentation/video4linux/gspca.txt
··· 275 275 pac7302 093a:262a Webcam 300k 276 276 pac7302 093a:262c Philips SPC 230 NC 277 277 jeilinj 0979:0280 Sakar 57379 278 + jeilinj 0979:0280 Sportscam DV15 278 279 zc3xx 0ac8:0302 Z-star Vimicro zc0302 279 280 vc032x 0ac8:0321 Vimicro generic vc0321 280 281 vc032x 0ac8:0323 Vimicro Vc0323
+67 -31
drivers/media/video/gspca/jeilinj.c
··· 34 34 35 35 /* Default timeouts, in ms */ 36 36 #define JEILINJ_CMD_TIMEOUT 500 37 + #define JEILINJ_CMD_DELAY 160 37 38 #define JEILINJ_DATA_TIMEOUT 1000 38 39 39 40 /* Maximum transfer size to use. */ ··· 42 41 #define FRAME_HEADER_LEN 0x10 43 42 #define FRAME_START 0xFFFFFFFF 44 43 44 + enum { 45 + SAKAR_57379, 46 + SPORTSCAM_DV15, 47 + }; 45 48 /* Structure to hold all of our device specific stuff */ 46 49 struct sd { 47 50 struct gspca_dev gspca_dev; /* !! must be the first item */ 48 51 int blocks_left; 49 52 const struct v4l2_pix_format *cap_mode; 50 53 /* Driver stuff */ 54 + u8 type; 51 55 u8 quality; /* image quality */ 52 56 u8 jpeg_hdr[JPEG_HDR_SZ]; 53 57 }; ··· 60 54 struct jlj_command { 61 55 unsigned char instruction[2]; 62 56 unsigned char ack_wanted; 57 + unsigned char delay; 63 58 }; 64 59 65 60 /* AFAICT these cameras will only do 320x240. */ ··· 121 114 static int jlj_start(struct gspca_dev *gspca_dev) 122 115 { 123 116 int i; 117 + int start_commands_size; 124 118 u8 response = 0xff; 125 119 struct sd *sd = (struct sd *) gspca_dev; 126 120 struct jlj_command start_commands[] = { 127 - {{0x71, 0x81}, 0}, 128 - {{0x70, 0x05}, 0}, 129 - {{0x95, 0x70}, 1}, 130 - {{0x71, 0x81}, 0}, 131 - {{0x70, 0x04}, 0}, 132 - {{0x95, 0x70}, 1}, 133 - {{0x71, 0x00}, 0}, 134 - {{0x70, 0x08}, 0}, 135 - {{0x95, 0x70}, 1}, 136 - {{0x94, 0x02}, 0}, 137 - {{0xde, 0x24}, 0}, 138 - {{0x94, 0x02}, 0}, 139 - {{0xdd, 0xf0}, 0}, 140 - {{0x94, 0x02}, 0}, 141 - {{0xe3, 0x2c}, 0}, 142 - {{0x94, 0x02}, 0}, 143 - {{0xe4, 0x00}, 0}, 144 - {{0x94, 0x02}, 0}, 145 - {{0xe5, 0x00}, 0}, 146 - {{0x94, 0x02}, 0}, 147 - {{0xe6, 0x2c}, 0}, 148 - {{0x94, 0x03}, 0}, 149 - {{0xaa, 0x00}, 0}, 150 - {{0x71, 0x1e}, 0}, 151 - {{0x70, 0x06}, 0}, 152 - {{0x71, 0x80}, 0}, 153 - {{0x70, 0x07}, 0} 121 + {{0x71, 0x81}, 0, 0}, 122 + {{0x70, 0x05}, 0, JEILINJ_CMD_DELAY}, 123 + {{0x95, 0x70}, 1, 0}, 124 + {{0x71, 0x81 - gspca_dev->curr_mode}, 0, 0}, 125 + {{0x70, 0x04}, 0, JEILINJ_CMD_DELAY}, 126 + {{0x95, 0x70}, 1, 0}, 127 + {{0x71, 0x00}, 0, 0}, /* start streaming ??*/ 128 + {{0x70, 0x08}, 0, JEILINJ_CMD_DELAY}, 129 + {{0x95, 0x70}, 1, 0}, 130 + #define SPORTSCAM_DV15_CMD_SIZE 9 131 + {{0x94, 0x02}, 0, 0}, 132 + {{0xde, 0x24}, 0, 0}, 133 + {{0x94, 0x02}, 0, 0}, 134 + {{0xdd, 0xf0}, 0, 0}, 135 + {{0x94, 0x02}, 0, 0}, 136 + {{0xe3, 0x2c}, 0, 0}, 137 + {{0x94, 0x02}, 0, 0}, 138 + {{0xe4, 0x00}, 0, 0}, 139 + {{0x94, 0x02}, 0, 0}, 140 + {{0xe5, 0x00}, 0, 0}, 141 + {{0x94, 0x02}, 0, 0}, 142 + {{0xe6, 0x2c}, 0, 0}, 143 + {{0x94, 0x03}, 0, 0}, 144 + {{0xaa, 0x00}, 0, 0}, 145 + {{0x71, 0x1e}, 0, 0}, 146 + {{0x70, 0x06}, 0, 0}, 147 + {{0x71, 0x80}, 0, 0}, 148 + {{0x70, 0x07}, 0, 0} 154 149 }; 155 150 156 151 sd->blocks_left = 0; 157 - for (i = 0; i < ARRAY_SIZE(start_commands); i++) { 152 + /* Under Windows, USB spy shows that only the 9 first start 153 + * commands are used for SPORTSCAM_DV15 webcam 154 + */ 155 + if (sd->type == SPORTSCAM_DV15) 156 + start_commands_size = SPORTSCAM_DV15_CMD_SIZE; 157 + else 158 + start_commands_size = ARRAY_SIZE(start_commands); 159 + 160 + for (i = 0; i < start_commands_size; i++) { 158 161 jlj_write2(gspca_dev, start_commands[i].instruction); 162 + if (start_commands[i].delay) 163 + msleep(start_commands[i].delay); 159 164 if (start_commands[i].ack_wanted) 160 165 jlj_read1(gspca_dev, response); 161 166 } ··· 226 207 struct cam *cam = &gspca_dev->cam; 227 208 struct sd *dev = (struct sd *) gspca_dev; 228 209 210 + dev->type = id->driver_info; 229 211 dev->quality = 85; 230 212 PDEBUG(D_PROBE, 231 213 "JEILINJ camera detected" ··· 297 277 298 278 /* Table of supported USB devices */ 299 279 static const struct usb_device_id device_table[] = { 300 - {USB_DEVICE(0x0979, 0x0280)}, 280 + {USB_DEVICE(0x0979, 0x0280), .driver_info = SAKAR_57379}, 281 + {USB_DEVICE(0x0979, 0x0270), .driver_info = SPORTSCAM_DV15}, 301 282 {} 302 283 }; 303 284 304 285 MODULE_DEVICE_TABLE(usb, device_table); 305 286 306 287 /* sub-driver description */ 307 - static const struct sd_desc sd_desc = { 288 + static const struct sd_desc sd_desc_sakar_57379 = { 308 289 .name = MODULE_NAME, 309 290 .config = sd_config, 310 291 .init = sd_init, ··· 314 293 .pkt_scan = sd_pkt_scan, 315 294 }; 316 295 296 + /* sub-driver description */ 297 + static const struct sd_desc sd_desc_sportscam_dv15 = { 298 + .name = MODULE_NAME, 299 + .config = sd_config, 300 + .init = sd_init, 301 + .start = sd_start, 302 + .stopN = sd_stopN, 303 + .pkt_scan = sd_pkt_scan, 304 + }; 305 + 306 + static const struct sd_desc *sd_desc[2] = { 307 + &sd_desc_sakar_57379, 308 + &sd_desc_sportscam_dv15 309 + }; 310 + 317 311 /* -- device connect -- */ 318 312 static int sd_probe(struct usb_interface *intf, 319 313 const struct usb_device_id *id) 320 314 { 321 315 return gspca_dev_probe(intf, id, 322 - &sd_desc, 316 + sd_desc[id->driver_info], 323 317 sizeof(struct sd), 324 318 THIS_MODULE); 325 319 }