]>
Commit | Line | Data |
---|---|---|
4c98834a EA |
1 | /* |
2 | * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher | |
3 | * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland | |
4 | * Copyright (c) 2002, 2003 Tuukka Toivonen | |
5 | * Copyright (c) 2008 Erik Andrén | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with this program; if not, write to the Free Software | |
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
20 | * | |
21 | * P/N 861037: Sensor HDCS1000 ASIC STV0600 | |
22 | * P/N 861050-0010: Sensor HDCS1000 ASIC STV0600 | |
23 | * P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 - QuickCam Express | |
24 | * P/N 861055: Sensor ST VV6410 ASIC STV0610 - LEGO cam | |
25 | * P/N 861075-0040: Sensor HDCS1000 ASIC | |
26 | * P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 - Dexxa WebCam USB | |
27 | * P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 - QuickCam Web | |
28 | */ | |
29 | ||
133a9fe9 JP |
30 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
31 | ||
0158e98f | 32 | #include <linux/input.h> |
4c98834a EA |
33 | #include "stv06xx_sensor.h" |
34 | ||
35 | MODULE_AUTHOR("Erik Andrén"); | |
36 | MODULE_DESCRIPTION("STV06XX USB Camera Driver"); | |
37 | MODULE_LICENSE("GPL"); | |
38 | ||
90ab5ee9 RR |
39 | static bool dump_bridge; |
40 | static bool dump_sensor; | |
4c98834a EA |
41 | |
42 | int stv06xx_write_bridge(struct sd *sd, u16 address, u16 i2c_data) | |
43 | { | |
44 | int err; | |
45 | struct usb_device *udev = sd->gspca_dev.dev; | |
46 | __u8 *buf = sd->gspca_dev.usb_buf; | |
47 | u8 len = (i2c_data > 0xff) ? 2 : 1; | |
48 | ||
49 | buf[0] = i2c_data & 0xff; | |
50 | buf[1] = (i2c_data >> 8) & 0xff; | |
51 | ||
52 | err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | |
53 | 0x04, 0x40, address, 0, buf, len, | |
54 | STV06XX_URB_MSG_TIMEOUT); | |
55 | ||
4c98834a EA |
56 | PDEBUG(D_CONF, "Written 0x%x to address 0x%x, status: %d", |
57 | i2c_data, address, err); | |
58 | ||
59 | return (err < 0) ? err : 0; | |
60 | } | |
61 | ||
62 | int stv06xx_read_bridge(struct sd *sd, u16 address, u8 *i2c_data) | |
63 | { | |
64 | int err; | |
65 | struct usb_device *udev = sd->gspca_dev.dev; | |
66 | __u8 *buf = sd->gspca_dev.usb_buf; | |
67 | ||
68 | err = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | |
69 | 0x04, 0xc0, address, 0, buf, 1, | |
70 | STV06XX_URB_MSG_TIMEOUT); | |
71 | ||
72 | *i2c_data = buf[0]; | |
73 | ||
be3bdfb6 | 74 | PDEBUG(D_CONF, "Reading 0x%x from address 0x%x, status %d", |
4c98834a EA |
75 | *i2c_data, address, err); |
76 | ||
77 | return (err < 0) ? err : 0; | |
78 | } | |
79 | ||
80 | /* Wraps the normal write sensor bytes / words functions for writing a | |
81 | single value */ | |
82 | int stv06xx_write_sensor(struct sd *sd, u8 address, u16 value) | |
83 | { | |
84 | if (sd->sensor->i2c_len == 2) { | |
85 | u16 data[2] = { address, value }; | |
86 | return stv06xx_write_sensor_words(sd, data, 1); | |
87 | } else { | |
88 | u8 data[2] = { address, value }; | |
89 | return stv06xx_write_sensor_bytes(sd, data, 1); | |
90 | } | |
91 | } | |
92 | ||
93 | static int stv06xx_write_sensor_finish(struct sd *sd) | |
94 | { | |
95 | int err = 0; | |
96 | ||
8668d504 | 97 | if (sd->bridge == BRIDGE_STV610) { |
4c98834a EA |
98 | struct usb_device *udev = sd->gspca_dev.dev; |
99 | __u8 *buf = sd->gspca_dev.usb_buf; | |
100 | ||
4c98834a EA |
101 | buf[0] = 0; |
102 | err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | |
103 | 0x04, 0x40, 0x1704, 0, buf, 1, | |
104 | STV06XX_URB_MSG_TIMEOUT); | |
105 | } | |
106 | ||
107 | return (err < 0) ? err : 0; | |
108 | } | |
109 | ||
110 | int stv06xx_write_sensor_bytes(struct sd *sd, const u8 *data, u8 len) | |
111 | { | |
112 | int err, i, j; | |
113 | struct usb_device *udev = sd->gspca_dev.dev; | |
114 | __u8 *buf = sd->gspca_dev.usb_buf; | |
115 | ||
be3bdfb6 | 116 | PDEBUG(D_CONF, "I2C: Command buffer contains %d entries", len); |
4c98834a EA |
117 | for (i = 0; i < len;) { |
118 | /* Build the command buffer */ | |
119 | memset(buf, 0, I2C_BUFFER_LENGTH); | |
120 | for (j = 0; j < I2C_MAX_BYTES && i < len; j++, i++) { | |
121 | buf[j] = data[2*i]; | |
122 | buf[0x10 + j] = data[2*i+1]; | |
be3bdfb6 | 123 | PDEBUG(D_CONF, "I2C: Writing 0x%02x to reg 0x%02x", |
4c98834a EA |
124 | data[2*i+1], data[2*i]); |
125 | } | |
126 | buf[0x20] = sd->sensor->i2c_addr; | |
127 | buf[0x21] = j - 1; /* Number of commands to send - 1 */ | |
128 | buf[0x22] = I2C_WRITE_CMD; | |
129 | err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | |
130 | 0x04, 0x40, 0x0400, 0, buf, | |
131 | I2C_BUFFER_LENGTH, | |
132 | STV06XX_URB_MSG_TIMEOUT); | |
a8ca20b2 EA |
133 | if (err < 0) |
134 | return err; | |
272ece5e MCC |
135 | } |
136 | return stv06xx_write_sensor_finish(sd); | |
4c98834a EA |
137 | } |
138 | ||
139 | int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len) | |
140 | { | |
141 | int err, i, j; | |
142 | struct usb_device *udev = sd->gspca_dev.dev; | |
143 | __u8 *buf = sd->gspca_dev.usb_buf; | |
144 | ||
be3bdfb6 | 145 | PDEBUG(D_CONF, "I2C: Command buffer contains %d entries", len); |
4c98834a EA |
146 | |
147 | for (i = 0; i < len;) { | |
148 | /* Build the command buffer */ | |
149 | memset(buf, 0, I2C_BUFFER_LENGTH); | |
150 | for (j = 0; j < I2C_MAX_WORDS && i < len; j++, i++) { | |
151 | buf[j] = data[2*i]; | |
152 | buf[0x10 + j * 2] = data[2*i+1]; | |
153 | buf[0x10 + j * 2 + 1] = data[2*i+1] >> 8; | |
be3bdfb6 | 154 | PDEBUG(D_CONF, "I2C: Writing 0x%04x to reg 0x%02x", |
4c98834a EA |
155 | data[2*i+1], data[2*i]); |
156 | } | |
157 | buf[0x20] = sd->sensor->i2c_addr; | |
158 | buf[0x21] = j - 1; /* Number of commands to send - 1 */ | |
159 | buf[0x22] = I2C_WRITE_CMD; | |
160 | err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | |
161 | 0x04, 0x40, 0x0400, 0, buf, | |
162 | I2C_BUFFER_LENGTH, | |
163 | STV06XX_URB_MSG_TIMEOUT); | |
164 | if (err < 0) | |
165 | return err; | |
166 | } | |
167 | return stv06xx_write_sensor_finish(sd); | |
168 | } | |
169 | ||
170 | int stv06xx_read_sensor(struct sd *sd, const u8 address, u16 *value) | |
171 | { | |
172 | int err; | |
173 | struct usb_device *udev = sd->gspca_dev.dev; | |
174 | __u8 *buf = sd->gspca_dev.usb_buf; | |
175 | ||
176 | err = stv06xx_write_bridge(sd, STV_I2C_FLUSH, sd->sensor->i2c_flush); | |
177 | if (err < 0) | |
178 | return err; | |
179 | ||
180 | /* Clear mem */ | |
181 | memset(buf, 0, I2C_BUFFER_LENGTH); | |
182 | ||
183 | buf[0] = address; | |
184 | buf[0x20] = sd->sensor->i2c_addr; | |
185 | buf[0x21] = 0; | |
186 | ||
187 | /* Read I2C register */ | |
188 | buf[0x22] = I2C_READ_CMD; | |
189 | ||
190 | err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | |
191 | 0x04, 0x40, 0x1400, 0, buf, I2C_BUFFER_LENGTH, | |
192 | STV06XX_URB_MSG_TIMEOUT); | |
193 | if (err < 0) { | |
133a9fe9 | 194 | pr_err("I2C: Read error writing address: %d\n", err); |
4c98834a EA |
195 | return err; |
196 | } | |
197 | ||
198 | err = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | |
199 | 0x04, 0xc0, 0x1410, 0, buf, sd->sensor->i2c_len, | |
200 | STV06XX_URB_MSG_TIMEOUT); | |
201 | if (sd->sensor->i2c_len == 2) | |
202 | *value = buf[0] | (buf[1] << 8); | |
203 | else | |
204 | *value = buf[0]; | |
205 | ||
be3bdfb6 | 206 | PDEBUG(D_CONF, "I2C: Read 0x%x from address 0x%x, status: %d", |
4c98834a EA |
207 | *value, address, err); |
208 | ||
209 | return (err < 0) ? err : 0; | |
210 | } | |
211 | ||
212 | /* Dumps all bridge registers */ | |
213 | static void stv06xx_dump_bridge(struct sd *sd) | |
214 | { | |
215 | int i; | |
216 | u8 data, buf; | |
217 | ||
133a9fe9 | 218 | pr_info("Dumping all stv06xx bridge registers\n"); |
4c98834a EA |
219 | for (i = 0x1400; i < 0x160f; i++) { |
220 | stv06xx_read_bridge(sd, i, &data); | |
221 | ||
133a9fe9 | 222 | pr_info("Read 0x%x from address 0x%x\n", data, i); |
4c98834a EA |
223 | } |
224 | ||
133a9fe9 | 225 | pr_info("Testing stv06xx bridge registers for writability\n"); |
4c98834a EA |
226 | for (i = 0x1400; i < 0x160f; i++) { |
227 | stv06xx_read_bridge(sd, i, &data); | |
228 | buf = data; | |
229 | ||
230 | stv06xx_write_bridge(sd, i, 0xff); | |
231 | stv06xx_read_bridge(sd, i, &data); | |
232 | if (data == 0xff) | |
133a9fe9 | 233 | pr_info("Register 0x%x is read/write\n", i); |
4c98834a | 234 | else if (data != buf) |
133a9fe9 JP |
235 | pr_info("Register 0x%x is read/write, but only partially\n", |
236 | i); | |
4c98834a | 237 | else |
133a9fe9 | 238 | pr_info("Register 0x%x is read-only\n", i); |
4c98834a EA |
239 | |
240 | stv06xx_write_bridge(sd, i, buf); | |
241 | } | |
242 | } | |
243 | ||
244 | /* this function is called at probe and resume time */ | |
245 | static int stv06xx_init(struct gspca_dev *gspca_dev) | |
246 | { | |
247 | struct sd *sd = (struct sd *) gspca_dev; | |
248 | int err; | |
249 | ||
250 | PDEBUG(D_PROBE, "Initializing camera"); | |
251 | ||
252 | /* Let the usb init settle for a bit | |
253 | before performing the initialization */ | |
254 | msleep(250); | |
255 | ||
256 | err = sd->sensor->init(sd); | |
257 | ||
8668d504 | 258 | if (dump_sensor && sd->sensor->dump) |
4c98834a EA |
259 | sd->sensor->dump(sd); |
260 | ||
261 | return (err < 0) ? err : 0; | |
262 | } | |
263 | ||
dec9c514 HV |
264 | /* this function is called at probe time */ |
265 | static int stv06xx_init_controls(struct gspca_dev *gspca_dev) | |
266 | { | |
267 | struct sd *sd = (struct sd *) gspca_dev; | |
268 | ||
269 | PDEBUG(D_PROBE, "Initializing controls"); | |
270 | ||
a8a47860 | 271 | gspca_dev->vdev.ctrl_handler = &gspca_dev->ctrl_handler; |
dec9c514 HV |
272 | return sd->sensor->init_controls(sd); |
273 | } | |
274 | ||
4c98834a EA |
275 | /* Start the camera */ |
276 | static int stv06xx_start(struct gspca_dev *gspca_dev) | |
277 | { | |
278 | struct sd *sd = (struct sd *) gspca_dev; | |
c0b33bdc HG |
279 | struct usb_host_interface *alt; |
280 | struct usb_interface *intf; | |
281 | int err, packet_size; | |
282 | ||
283 | intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface); | |
284 | alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); | |
285 | if (!alt) { | |
286 | PDEBUG(D_ERR, "Couldn't get altsetting"); | |
287 | return -EIO; | |
288 | } | |
289 | ||
290 | packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); | |
291 | err = stv06xx_write_bridge(sd, STV_ISO_SIZE_L, packet_size); | |
292 | if (err < 0) | |
293 | return err; | |
4c98834a EA |
294 | |
295 | /* Prepare the sensor for start */ | |
296 | err = sd->sensor->start(sd); | |
297 | if (err < 0) | |
298 | goto out; | |
299 | ||
300 | /* Start isochronous streaming */ | |
301 | err = stv06xx_write_bridge(sd, STV_ISO_ENABLE, 1); | |
302 | ||
303 | out: | |
304 | if (err < 0) | |
305 | PDEBUG(D_STREAM, "Starting stream failed"); | |
306 | else | |
307 | PDEBUG(D_STREAM, "Started streaming"); | |
308 | ||
309 | return (err < 0) ? err : 0; | |
310 | } | |
311 | ||
c0b33bdc HG |
312 | static int stv06xx_isoc_init(struct gspca_dev *gspca_dev) |
313 | { | |
314 | struct usb_host_interface *alt; | |
315 | struct sd *sd = (struct sd *) gspca_dev; | |
316 | ||
317 | /* Start isoc bandwidth "negotiation" at max isoc bandwidth */ | |
5dae603d | 318 | alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1]; |
c0b33bdc HG |
319 | alt->endpoint[0].desc.wMaxPacketSize = |
320 | cpu_to_le16(sd->sensor->max_packet_size[gspca_dev->curr_mode]); | |
321 | ||
322 | return 0; | |
323 | } | |
324 | ||
325 | static int stv06xx_isoc_nego(struct gspca_dev *gspca_dev) | |
326 | { | |
327 | int ret, packet_size, min_packet_size; | |
328 | struct usb_host_interface *alt; | |
329 | struct sd *sd = (struct sd *) gspca_dev; | |
330 | ||
5dae603d | 331 | alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1]; |
c0b33bdc HG |
332 | packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); |
333 | min_packet_size = sd->sensor->min_packet_size[gspca_dev->curr_mode]; | |
334 | if (packet_size <= min_packet_size) | |
335 | return -EIO; | |
336 | ||
337 | packet_size -= 100; | |
338 | if (packet_size < min_packet_size) | |
339 | packet_size = min_packet_size; | |
340 | alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(packet_size); | |
341 | ||
342 | ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); | |
343 | if (ret < 0) | |
344 | PDEBUG(D_ERR|D_STREAM, "set alt 1 err %d", ret); | |
345 | ||
346 | return ret; | |
347 | } | |
348 | ||
4c98834a EA |
349 | static void stv06xx_stopN(struct gspca_dev *gspca_dev) |
350 | { | |
351 | int err; | |
352 | struct sd *sd = (struct sd *) gspca_dev; | |
353 | ||
354 | /* stop ISO-streaming */ | |
355 | err = stv06xx_write_bridge(sd, STV_ISO_ENABLE, 0); | |
356 | if (err < 0) | |
357 | goto out; | |
358 | ||
359 | err = sd->sensor->stop(sd); | |
4c98834a EA |
360 | |
361 | out: | |
362 | if (err < 0) | |
363 | PDEBUG(D_STREAM, "Failed to stop stream"); | |
364 | else | |
365 | PDEBUG(D_STREAM, "Stopped streaming"); | |
366 | } | |
367 | ||
368 | /* | |
369 | * Analyse an USB packet of the data stream and store it appropriately. | |
370 | * Each packet contains an integral number of chunks. Each chunk has | |
371 | * 2-bytes identification, followed by 2-bytes that describe the chunk | |
372 | * length. Known/guessed chunk identifications are: | |
373 | * 8001/8005/C001/C005 - Begin new frame | |
374 | * 8002/8006/C002/C006 - End frame | |
375 | * 0200/4200 - Contains actual image data, bayer or compressed | |
376 | * 0005 - 11 bytes of unknown data | |
377 | * 0100 - 2 bytes of unknown data | |
378 | * The 0005 and 0100 chunks seem to appear only in compressed stream. | |
379 | */ | |
380 | static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev, | |
76dd272b | 381 | u8 *data, /* isoc packet */ |
4c98834a EA |
382 | int len) /* iso packet length */ |
383 | { | |
8668d504 HG |
384 | struct sd *sd = (struct sd *) gspca_dev; |
385 | ||
4c98834a EA |
386 | PDEBUG(D_PACK, "Packet of length %d arrived", len); |
387 | ||
388 | /* A packet may contain several frames | |
389 | loop until the whole packet is reached */ | |
390 | while (len) { | |
391 | int id, chunk_len; | |
392 | ||
393 | if (len < 4) { | |
394 | PDEBUG(D_PACK, "Packet is smaller than 4 bytes"); | |
395 | return; | |
396 | } | |
397 | ||
398 | /* Capture the id */ | |
399 | id = (data[0] << 8) | data[1]; | |
400 | ||
401 | /* Capture the chunk length */ | |
402 | chunk_len = (data[2] << 8) | data[3]; | |
403 | PDEBUG(D_PACK, "Chunk id: %x, length: %d", id, chunk_len); | |
404 | ||
405 | data += 4; | |
406 | len -= 4; | |
407 | ||
408 | if (len < chunk_len) { | |
409 | PDEBUG(D_ERR, "URB packet length is smaller" | |
410 | " than the specified chunk length"); | |
8668d504 | 411 | gspca_dev->last_packet_type = DISCARD_PACKET; |
4c98834a EA |
412 | return; |
413 | } | |
414 | ||
8668d504 | 415 | /* First byte seem to be 02=data 2nd byte is unknown??? */ |
1d00d6c1 | 416 | if (sd->bridge == BRIDGE_ST6422 && (id & 0xff00) == 0x0200) |
8668d504 HG |
417 | goto frame_data; |
418 | ||
4c98834a EA |
419 | switch (id) { |
420 | case 0x0200: | |
421 | case 0x4200: | |
8668d504 | 422 | frame_data: |
4c98834a EA |
423 | PDEBUG(D_PACK, "Frame data packet detected"); |
424 | ||
8668d504 HG |
425 | if (sd->to_skip) { |
426 | int skip = (sd->to_skip < chunk_len) ? | |
427 | sd->to_skip : chunk_len; | |
428 | data += skip; | |
429 | len -= skip; | |
430 | chunk_len -= skip; | |
431 | sd->to_skip -= skip; | |
432 | } | |
433 | ||
76dd272b | 434 | gspca_frame_add(gspca_dev, INTER_PACKET, |
4c98834a EA |
435 | data, chunk_len); |
436 | break; | |
437 | ||
438 | case 0x8001: | |
439 | case 0x8005: | |
440 | case 0xc001: | |
441 | case 0xc005: | |
442 | PDEBUG(D_PACK, "Starting new frame"); | |
443 | ||
444 | /* Create a new frame, chunk length should be zero */ | |
445 | gspca_frame_add(gspca_dev, FIRST_PACKET, | |
76dd272b | 446 | NULL, 0); |
4c98834a | 447 | |
8668d504 HG |
448 | if (sd->bridge == BRIDGE_ST6422) |
449 | sd->to_skip = gspca_dev->width * 4; | |
450 | ||
4c98834a EA |
451 | if (chunk_len) |
452 | PDEBUG(D_ERR, "Chunk length is " | |
453 | "non-zero on a SOF"); | |
454 | break; | |
455 | ||
456 | case 0x8002: | |
457 | case 0x8006: | |
458 | case 0xc002: | |
459 | PDEBUG(D_PACK, "End of frame detected"); | |
460 | ||
461 | /* Complete the last frame (if any) */ | |
76dd272b JFM |
462 | gspca_frame_add(gspca_dev, LAST_PACKET, |
463 | NULL, 0); | |
4c98834a EA |
464 | |
465 | if (chunk_len) | |
466 | PDEBUG(D_ERR, "Chunk length is " | |
467 | "non-zero on a EOF"); | |
468 | break; | |
469 | ||
470 | case 0x0005: | |
471 | PDEBUG(D_PACK, "Chunk 0x005 detected"); | |
472 | /* Unknown chunk with 11 bytes of data, | |
473 | occurs just before end of each frame | |
474 | in compressed mode */ | |
475 | break; | |
476 | ||
477 | case 0x0100: | |
478 | PDEBUG(D_PACK, "Chunk 0x0100 detected"); | |
479 | /* Unknown chunk with 2 bytes of data, | |
480 | occurs 2-3 times per USB interrupt */ | |
481 | break; | |
8668d504 HG |
482 | case 0x42ff: |
483 | PDEBUG(D_PACK, "Chunk 0x42ff detected"); | |
484 | /* Special chunk seen sometimes on the ST6422 */ | |
485 | break; | |
4c98834a | 486 | default: |
8668d504 | 487 | PDEBUG(D_PACK, "Unknown chunk 0x%04x detected", id); |
4c98834a EA |
488 | /* Unknown chunk */ |
489 | } | |
490 | data += chunk_len; | |
491 | len -= chunk_len; | |
492 | } | |
493 | } | |
494 | ||
00ddb707 | 495 | #if IS_ENABLED(CONFIG_INPUT) |
0158e98f HG |
496 | static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, |
497 | u8 *data, /* interrupt packet data */ | |
498 | int len) /* interrupt packet length */ | |
499 | { | |
500 | int ret = -EINVAL; | |
501 | ||
502 | if (len == 1 && data[0] == 0x80) { | |
503 | input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1); | |
504 | input_sync(gspca_dev->input_dev); | |
505 | ret = 0; | |
506 | } | |
507 | ||
508 | if (len == 1 && data[0] == 0x88) { | |
509 | input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); | |
510 | input_sync(gspca_dev->input_dev); | |
511 | ret = 0; | |
512 | } | |
513 | ||
514 | return ret; | |
515 | } | |
516 | #endif | |
517 | ||
4c98834a EA |
518 | static int stv06xx_config(struct gspca_dev *gspca_dev, |
519 | const struct usb_device_id *id); | |
520 | ||
521 | /* sub-driver description */ | |
522 | static const struct sd_desc sd_desc = { | |
523 | .name = MODULE_NAME, | |
524 | .config = stv06xx_config, | |
525 | .init = stv06xx_init, | |
dec9c514 | 526 | .init_controls = stv06xx_init_controls, |
4c98834a EA |
527 | .start = stv06xx_start, |
528 | .stopN = stv06xx_stopN, | |
0158e98f | 529 | .pkt_scan = stv06xx_pkt_scan, |
c0b33bdc HG |
530 | .isoc_init = stv06xx_isoc_init, |
531 | .isoc_nego = stv06xx_isoc_nego, | |
00ddb707 | 532 | #if IS_ENABLED(CONFIG_INPUT) |
0158e98f HG |
533 | .int_pkt_scan = sd_int_pkt_scan, |
534 | #endif | |
4c98834a EA |
535 | }; |
536 | ||
537 | /* This function is called at probe time */ | |
538 | static int stv06xx_config(struct gspca_dev *gspca_dev, | |
539 | const struct usb_device_id *id) | |
540 | { | |
541 | struct sd *sd = (struct sd *) gspca_dev; | |
4c98834a EA |
542 | |
543 | PDEBUG(D_PROBE, "Configuring camera"); | |
544 | ||
8668d504 | 545 | sd->bridge = id->driver_info; |
d67a1ada | 546 | gspca_dev->sd_desc = &sd_desc; |
4c98834a EA |
547 | |
548 | if (dump_bridge) | |
549 | stv06xx_dump_bridge(sd); | |
550 | ||
8668d504 HG |
551 | sd->sensor = &stv06xx_sensor_st6422; |
552 | if (!sd->sensor->probe(sd)) | |
553 | return 0; | |
554 | ||
4c98834a EA |
555 | sd->sensor = &stv06xx_sensor_vv6410; |
556 | if (!sd->sensor->probe(sd)) | |
557 | return 0; | |
558 | ||
559 | sd->sensor = &stv06xx_sensor_hdcs1x00; | |
560 | if (!sd->sensor->probe(sd)) | |
561 | return 0; | |
562 | ||
563 | sd->sensor = &stv06xx_sensor_hdcs1020; | |
564 | if (!sd->sensor->probe(sd)) | |
565 | return 0; | |
566 | ||
567 | sd->sensor = &stv06xx_sensor_pb0100; | |
568 | if (!sd->sensor->probe(sd)) | |
569 | return 0; | |
570 | ||
571 | sd->sensor = NULL; | |
572 | return -ENODEV; | |
573 | } | |
574 | ||
575 | ||
576 | ||
577 | /* -- module initialisation -- */ | |
95c967c1 | 578 | static const struct usb_device_id device_table[] = { |
8668d504 HG |
579 | /* QuickCam Express */ |
580 | {USB_DEVICE(0x046d, 0x0840), .driver_info = BRIDGE_STV600 }, | |
581 | /* LEGO cam / QuickCam Web */ | |
582 | {USB_DEVICE(0x046d, 0x0850), .driver_info = BRIDGE_STV610 }, | |
583 | /* Dexxa WebCam USB */ | |
584 | {USB_DEVICE(0x046d, 0x0870), .driver_info = BRIDGE_STV602 }, | |
585 | /* QuickCam Messenger */ | |
586 | {USB_DEVICE(0x046D, 0x08F0), .driver_info = BRIDGE_ST6422 }, | |
587 | /* QuickCam Communicate */ | |
588 | {USB_DEVICE(0x046D, 0x08F5), .driver_info = BRIDGE_ST6422 }, | |
589 | /* QuickCam Messenger (new) */ | |
590 | {USB_DEVICE(0x046D, 0x08F6), .driver_info = BRIDGE_ST6422 }, | |
4c98834a EA |
591 | {} |
592 | }; | |
593 | MODULE_DEVICE_TABLE(usb, device_table); | |
594 | ||
595 | /* -- device connect -- */ | |
596 | static int sd_probe(struct usb_interface *intf, | |
597 | const struct usb_device_id *id) | |
598 | { | |
599 | PDEBUG(D_PROBE, "Probing for a stv06xx device"); | |
600 | return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), | |
601 | THIS_MODULE); | |
602 | } | |
603 | ||
8a787b40 | 604 | static void sd_disconnect(struct usb_interface *intf) |
4c98834a EA |
605 | { |
606 | struct gspca_dev *gspca_dev = usb_get_intfdata(intf); | |
607 | struct sd *sd = (struct sd *) gspca_dev; | |
dec9c514 | 608 | void *priv = sd->sensor_priv; |
4c98834a EA |
609 | PDEBUG(D_PROBE, "Disconnecting the stv06xx device"); |
610 | ||
dec9c514 | 611 | sd->sensor = NULL; |
4c98834a | 612 | gspca_disconnect(intf); |
dec9c514 | 613 | kfree(priv); |
4c98834a EA |
614 | } |
615 | ||
616 | static struct usb_driver sd_driver = { | |
617 | .name = MODULE_NAME, | |
618 | .id_table = device_table, | |
619 | .probe = sd_probe, | |
620 | .disconnect = sd_disconnect, | |
621 | #ifdef CONFIG_PM | |
622 | .suspend = gspca_suspend, | |
623 | .resume = gspca_resume, | |
dec9c514 | 624 | .reset_resume = gspca_resume, |
4c98834a EA |
625 | #endif |
626 | }; | |
627 | ||
ecb3b2b3 | 628 | module_usb_driver(sd_driver); |
4c98834a EA |
629 | |
630 | module_param(dump_bridge, bool, S_IRUGO | S_IWUSR); | |
631 | MODULE_PARM_DESC(dump_bridge, "Dumps all usb bridge registers at startup"); | |
632 | ||
633 | module_param(dump_sensor, bool, S_IRUGO | S_IWUSR); | |
634 | MODULE_PARM_DESC(dump_sensor, "Dumps all sensor registers at startup"); |