diff options
author | Patrice Chotard <patrice.chotard@sfr.fr> | 2011-04-18 16:40:54 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-05-20 08:27:21 -0400 |
commit | 713b466f0f67de2d9dc9de85741fffd8516b34fb (patch) | |
tree | 1471cf2500c0431611a67496b4d5f3167efd4664 | |
parent | 6f8efcfb3dc88e4c626765278afc40ed4bfc18e2 (diff) |
[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>
-rw-r--r-- | Documentation/video4linux/gspca.txt | 1 | ||||
-rw-r--r-- | drivers/media/video/gspca/jeilinj.c | 98 |
2 files changed, 68 insertions, 31 deletions
diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt index 5c542e60f51..5bfa9a777d2 100644 --- a/Documentation/video4linux/gspca.txt +++ b/Documentation/video4linux/gspca.txt | |||
@@ -275,6 +275,7 @@ pac7302 093a:2629 Genious iSlim 300 | |||
275 | pac7302 093a:262a Webcam 300k | 275 | pac7302 093a:262a Webcam 300k |
276 | pac7302 093a:262c Philips SPC 230 NC | 276 | pac7302 093a:262c Philips SPC 230 NC |
277 | jeilinj 0979:0280 Sakar 57379 | 277 | jeilinj 0979:0280 Sakar 57379 |
278 | jeilinj 0979:0280 Sportscam DV15 | ||
278 | zc3xx 0ac8:0302 Z-star Vimicro zc0302 | 279 | zc3xx 0ac8:0302 Z-star Vimicro zc0302 |
279 | vc032x 0ac8:0321 Vimicro generic vc0321 | 280 | vc032x 0ac8:0321 Vimicro generic vc0321 |
280 | vc032x 0ac8:0323 Vimicro Vc0323 | 281 | vc032x 0ac8:0323 Vimicro Vc0323 |
diff --git a/drivers/media/video/gspca/jeilinj.c b/drivers/media/video/gspca/jeilinj.c index 51b68dbdcdb..da92867fb27 100644 --- a/drivers/media/video/gspca/jeilinj.c +++ b/drivers/media/video/gspca/jeilinj.c | |||
@@ -34,6 +34,7 @@ MODULE_LICENSE("GPL"); | |||
34 | 34 | ||
35 | /* Default timeouts, in ms */ | 35 | /* Default timeouts, in ms */ |
36 | #define JEILINJ_CMD_TIMEOUT 500 | 36 | #define JEILINJ_CMD_TIMEOUT 500 |
37 | #define JEILINJ_CMD_DELAY 160 | ||
37 | #define JEILINJ_DATA_TIMEOUT 1000 | 38 | #define JEILINJ_DATA_TIMEOUT 1000 |
38 | 39 | ||
39 | /* Maximum transfer size to use. */ | 40 | /* Maximum transfer size to use. */ |
@@ -41,12 +42,17 @@ MODULE_LICENSE("GPL"); | |||
41 | #define FRAME_HEADER_LEN 0x10 | 42 | #define FRAME_HEADER_LEN 0x10 |
42 | #define FRAME_START 0xFFFFFFFF | 43 | #define FRAME_START 0xFFFFFFFF |
43 | 44 | ||
45 | enum { | ||
46 | SAKAR_57379, | ||
47 | SPORTSCAM_DV15, | ||
48 | }; | ||
44 | /* Structure to hold all of our device specific stuff */ | 49 | /* Structure to hold all of our device specific stuff */ |
45 | struct sd { | 50 | struct sd { |
46 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 51 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
47 | int blocks_left; | 52 | int blocks_left; |
48 | const struct v4l2_pix_format *cap_mode; | 53 | const struct v4l2_pix_format *cap_mode; |
49 | /* Driver stuff */ | 54 | /* Driver stuff */ |
55 | u8 type; | ||
50 | u8 quality; /* image quality */ | 56 | u8 quality; /* image quality */ |
51 | u8 jpeg_hdr[JPEG_HDR_SZ]; | 57 | u8 jpeg_hdr[JPEG_HDR_SZ]; |
52 | }; | 58 | }; |
@@ -54,6 +60,7 @@ struct sd { | |||
54 | struct jlj_command { | 60 | struct jlj_command { |
55 | unsigned char instruction[2]; | 61 | unsigned char instruction[2]; |
56 | unsigned char ack_wanted; | 62 | unsigned char ack_wanted; |
63 | unsigned char delay; | ||
57 | }; | 64 | }; |
58 | 65 | ||
59 | /* AFAICT these cameras will only do 320x240. */ | 66 | /* AFAICT these cameras will only do 320x240. */ |
@@ -114,41 +121,53 @@ static void jlj_read1(struct gspca_dev *gspca_dev, unsigned char response) | |||
114 | static int jlj_start(struct gspca_dev *gspca_dev) | 121 | static int jlj_start(struct gspca_dev *gspca_dev) |
115 | { | 122 | { |
116 | int i; | 123 | int i; |
124 | int start_commands_size; | ||
117 | u8 response = 0xff; | 125 | u8 response = 0xff; |
118 | struct sd *sd = (struct sd *) gspca_dev; | 126 | struct sd *sd = (struct sd *) gspca_dev; |
119 | struct jlj_command start_commands[] = { | 127 | struct jlj_command start_commands[] = { |
120 | {{0x71, 0x81}, 0}, | 128 | {{0x71, 0x81}, 0, 0}, |
121 | {{0x70, 0x05}, 0}, | 129 | {{0x70, 0x05}, 0, JEILINJ_CMD_DELAY}, |
122 | {{0x95, 0x70}, 1}, | 130 | {{0x95, 0x70}, 1, 0}, |
123 | {{0x71, 0x81}, 0}, | 131 | {{0x71, 0x81 - gspca_dev->curr_mode}, 0, 0}, |
124 | {{0x70, 0x04}, 0}, | 132 | {{0x70, 0x04}, 0, JEILINJ_CMD_DELAY}, |
125 | {{0x95, 0x70}, 1}, | 133 | {{0x95, 0x70}, 1, 0}, |
126 | {{0x71, 0x00}, 0}, | 134 | {{0x71, 0x00}, 0, 0}, /* start streaming ??*/ |
127 | {{0x70, 0x08}, 0}, | 135 | {{0x70, 0x08}, 0, JEILINJ_CMD_DELAY}, |
128 | {{0x95, 0x70}, 1}, | 136 | {{0x95, 0x70}, 1, 0}, |
129 | {{0x94, 0x02}, 0}, | 137 | #define SPORTSCAM_DV15_CMD_SIZE 9 |
130 | {{0xde, 0x24}, 0}, | 138 | {{0x94, 0x02}, 0, 0}, |
131 | {{0x94, 0x02}, 0}, | 139 | {{0xde, 0x24}, 0, 0}, |
132 | {{0xdd, 0xf0}, 0}, | 140 | {{0x94, 0x02}, 0, 0}, |
133 | {{0x94, 0x02}, 0}, | 141 | {{0xdd, 0xf0}, 0, 0}, |
134 | {{0xe3, 0x2c}, 0}, | 142 | {{0x94, 0x02}, 0, 0}, |
135 | {{0x94, 0x02}, 0}, | 143 | {{0xe3, 0x2c}, 0, 0}, |
136 | {{0xe4, 0x00}, 0}, | 144 | {{0x94, 0x02}, 0, 0}, |
137 | {{0x94, 0x02}, 0}, | 145 | {{0xe4, 0x00}, 0, 0}, |
138 | {{0xe5, 0x00}, 0}, | 146 | {{0x94, 0x02}, 0, 0}, |
139 | {{0x94, 0x02}, 0}, | 147 | {{0xe5, 0x00}, 0, 0}, |
140 | {{0xe6, 0x2c}, 0}, | 148 | {{0x94, 0x02}, 0, 0}, |
141 | {{0x94, 0x03}, 0}, | 149 | {{0xe6, 0x2c}, 0, 0}, |
142 | {{0xaa, 0x00}, 0}, | 150 | {{0x94, 0x03}, 0, 0}, |
143 | {{0x71, 0x1e}, 0}, | 151 | {{0xaa, 0x00}, 0, 0}, |
144 | {{0x70, 0x06}, 0}, | 152 | {{0x71, 0x1e}, 0, 0}, |
145 | {{0x71, 0x80}, 0}, | 153 | {{0x70, 0x06}, 0, 0}, |
146 | {{0x70, 0x07}, 0} | 154 | {{0x71, 0x80}, 0, 0}, |
155 | {{0x70, 0x07}, 0, 0} | ||
147 | }; | 156 | }; |
148 | 157 | ||
149 | sd->blocks_left = 0; | 158 | sd->blocks_left = 0; |
150 | for (i = 0; i < ARRAY_SIZE(start_commands); i++) { | 159 | /* Under Windows, USB spy shows that only the 9 first start |
160 | * commands are used for SPORTSCAM_DV15 webcam | ||
161 | */ | ||
162 | if (sd->type == SPORTSCAM_DV15) | ||
163 | start_commands_size = SPORTSCAM_DV15_CMD_SIZE; | ||
164 | else | ||
165 | start_commands_size = ARRAY_SIZE(start_commands); | ||
166 | |||
167 | for (i = 0; i < start_commands_size; i++) { | ||
151 | jlj_write2(gspca_dev, start_commands[i].instruction); | 168 | jlj_write2(gspca_dev, start_commands[i].instruction); |
169 | if (start_commands[i].delay) | ||
170 | msleep(start_commands[i].delay); | ||
152 | if (start_commands[i].ack_wanted) | 171 | if (start_commands[i].ack_wanted) |
153 | jlj_read1(gspca_dev, response); | 172 | jlj_read1(gspca_dev, response); |
154 | } | 173 | } |
@@ -207,6 +226,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
207 | struct cam *cam = &gspca_dev->cam; | 226 | struct cam *cam = &gspca_dev->cam; |
208 | struct sd *dev = (struct sd *) gspca_dev; | 227 | struct sd *dev = (struct sd *) gspca_dev; |
209 | 228 | ||
229 | dev->type = id->driver_info; | ||
210 | dev->quality = 85; | 230 | dev->quality = 85; |
211 | PDEBUG(D_PROBE, | 231 | PDEBUG(D_PROBE, |
212 | "JEILINJ camera detected" | 232 | "JEILINJ camera detected" |
@@ -277,14 +297,25 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
277 | 297 | ||
278 | /* Table of supported USB devices */ | 298 | /* Table of supported USB devices */ |
279 | static const struct usb_device_id device_table[] = { | 299 | static const struct usb_device_id device_table[] = { |
280 | {USB_DEVICE(0x0979, 0x0280)}, | 300 | {USB_DEVICE(0x0979, 0x0280), .driver_info = SAKAR_57379}, |
301 | {USB_DEVICE(0x0979, 0x0270), .driver_info = SPORTSCAM_DV15}, | ||
281 | {} | 302 | {} |
282 | }; | 303 | }; |
283 | 304 | ||
284 | MODULE_DEVICE_TABLE(usb, device_table); | 305 | MODULE_DEVICE_TABLE(usb, device_table); |
285 | 306 | ||
286 | /* sub-driver description */ | 307 | /* sub-driver description */ |
287 | static const struct sd_desc sd_desc = { | 308 | static const struct sd_desc sd_desc_sakar_57379 = { |
309 | .name = MODULE_NAME, | ||
310 | .config = sd_config, | ||
311 | .init = sd_init, | ||
312 | .start = sd_start, | ||
313 | .stopN = sd_stopN, | ||
314 | .pkt_scan = sd_pkt_scan, | ||
315 | }; | ||
316 | |||
317 | /* sub-driver description */ | ||
318 | static const struct sd_desc sd_desc_sportscam_dv15 = { | ||
288 | .name = MODULE_NAME, | 319 | .name = MODULE_NAME, |
289 | .config = sd_config, | 320 | .config = sd_config, |
290 | .init = sd_init, | 321 | .init = sd_init, |
@@ -293,12 +324,17 @@ static const struct sd_desc sd_desc = { | |||
293 | .pkt_scan = sd_pkt_scan, | 324 | .pkt_scan = sd_pkt_scan, |
294 | }; | 325 | }; |
295 | 326 | ||
327 | static const struct sd_desc *sd_desc[2] = { | ||
328 | &sd_desc_sakar_57379, | ||
329 | &sd_desc_sportscam_dv15 | ||
330 | }; | ||
331 | |||
296 | /* -- device connect -- */ | 332 | /* -- device connect -- */ |
297 | static int sd_probe(struct usb_interface *intf, | 333 | static int sd_probe(struct usb_interface *intf, |
298 | const struct usb_device_id *id) | 334 | const struct usb_device_id *id) |
299 | { | 335 | { |
300 | return gspca_dev_probe(intf, id, | 336 | return gspca_dev_probe(intf, id, |
301 | &sd_desc, | 337 | sd_desc[id->driver_info], |
302 | sizeof(struct sd), | 338 | sizeof(struct sd), |
303 | THIS_MODULE); | 339 | THIS_MODULE); |
304 | } | 340 | } |