diff options
Diffstat (limited to 'drivers/media/video/gspca/sq905c.c')
-rw-r--r-- | drivers/media/video/gspca/sq905c.c | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c index d70b156872d6..e64662052992 100644 --- a/drivers/media/video/gspca/sq905c.c +++ b/drivers/media/video/gspca/sq905c.c | |||
@@ -47,6 +47,7 @@ MODULE_LICENSE("GPL"); | |||
47 | 47 | ||
48 | /* Commands. These go in the "value" slot. */ | 48 | /* Commands. These go in the "value" slot. */ |
49 | #define SQ905C_CLEAR 0xa0 /* clear everything */ | 49 | #define SQ905C_CLEAR 0xa0 /* clear everything */ |
50 | #define SQ905C_GET_ID 0x14f4 /* Read version number */ | ||
50 | #define SQ905C_CAPTURE_LOW 0xa040 /* Starts capture at 160x120 */ | 51 | #define SQ905C_CAPTURE_LOW 0xa040 /* Starts capture at 160x120 */ |
51 | #define SQ905C_CAPTURE_MED 0x1440 /* Starts capture at 320x240 */ | 52 | #define SQ905C_CAPTURE_MED 0x1440 /* Starts capture at 320x240 */ |
52 | #define SQ905C_CAPTURE_HI 0x2840 /* Starts capture at 320x240 */ | 53 | #define SQ905C_CAPTURE_HI 0x2840 /* Starts capture at 320x240 */ |
@@ -101,6 +102,26 @@ static int sq905c_command(struct gspca_dev *gspca_dev, u16 command, u16 index) | |||
101 | return 0; | 102 | return 0; |
102 | } | 103 | } |
103 | 104 | ||
105 | static int sq905c_read(struct gspca_dev *gspca_dev, u16 command, u16 index, | ||
106 | int size) | ||
107 | { | ||
108 | int ret; | ||
109 | |||
110 | ret = usb_control_msg(gspca_dev->dev, | ||
111 | usb_rcvctrlpipe(gspca_dev->dev, 0), | ||
112 | USB_REQ_SYNCH_FRAME, /* request */ | ||
113 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
114 | command, index, gspca_dev->usb_buf, size, | ||
115 | SQ905C_CMD_TIMEOUT); | ||
116 | if (ret < 0) { | ||
117 | PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", | ||
118 | __func__, ret); | ||
119 | return ret; | ||
120 | } | ||
121 | |||
122 | return 0; | ||
123 | } | ||
124 | |||
104 | /* This function is called as a workqueue function and runs whenever the camera | 125 | /* This function is called as a workqueue function and runs whenever the camera |
105 | * is streaming data. Because it is a workqueue function it is allowed to sleep | 126 | * is streaming data. Because it is a workqueue function it is allowed to sleep |
106 | * so we can use synchronous USB calls. To avoid possible collisions with other | 127 | * so we can use synchronous USB calls. To avoid possible collisions with other |
@@ -183,13 +204,34 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
183 | { | 204 | { |
184 | struct cam *cam = &gspca_dev->cam; | 205 | struct cam *cam = &gspca_dev->cam; |
185 | struct sd *dev = (struct sd *) gspca_dev; | 206 | struct sd *dev = (struct sd *) gspca_dev; |
207 | int ret; | ||
186 | 208 | ||
187 | PDEBUG(D_PROBE, | 209 | PDEBUG(D_PROBE, |
188 | "SQ9050 camera detected" | 210 | "SQ9050 camera detected" |
189 | " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); | 211 | " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); |
212 | |||
213 | ret = sq905c_command(gspca_dev, SQ905C_GET_ID, 0); | ||
214 | if (ret < 0) { | ||
215 | PDEBUG(D_ERR, "Get version command failed"); | ||
216 | return ret; | ||
217 | } | ||
218 | |||
219 | ret = sq905c_read(gspca_dev, 0xf5, 0, 20); | ||
220 | if (ret < 0) { | ||
221 | PDEBUG(D_ERR, "Reading version command failed"); | ||
222 | return ret; | ||
223 | } | ||
224 | /* Note we leave out the usb id and the manufacturing date */ | ||
225 | PDEBUG(D_PROBE, | ||
226 | "SQ9050 ID string: %02x - %02x %02x %02x %02x %02x %02x", | ||
227 | gspca_dev->usb_buf[3], | ||
228 | gspca_dev->usb_buf[14], gspca_dev->usb_buf[15], | ||
229 | gspca_dev->usb_buf[16], gspca_dev->usb_buf[17], | ||
230 | gspca_dev->usb_buf[18], gspca_dev->usb_buf[19]); | ||
231 | |||
190 | cam->cam_mode = sq905c_mode; | 232 | cam->cam_mode = sq905c_mode; |
191 | cam->nmodes = 2; | 233 | cam->nmodes = 2; |
192 | if (id->idProduct == 0x9050) | 234 | if (gspca_dev->usb_buf[15] == 0) |
193 | cam->nmodes = 1; | 235 | cam->nmodes = 1; |
194 | /* We don't use the buffer gspca allocates so make it small. */ | 236 | /* We don't use the buffer gspca allocates so make it small. */ |
195 | cam->bulk_size = 32; | 237 | cam->bulk_size = 32; |
@@ -258,6 +300,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
258 | static const __devinitdata struct usb_device_id device_table[] = { | 300 | static const __devinitdata struct usb_device_id device_table[] = { |
259 | {USB_DEVICE(0x2770, 0x905c)}, | 301 | {USB_DEVICE(0x2770, 0x905c)}, |
260 | {USB_DEVICE(0x2770, 0x9050)}, | 302 | {USB_DEVICE(0x2770, 0x9050)}, |
303 | {USB_DEVICE(0x2770, 0x9052)}, | ||
261 | {USB_DEVICE(0x2770, 0x913d)}, | 304 | {USB_DEVICE(0x2770, 0x913d)}, |
262 | {} | 305 | {} |
263 | }; | 306 | }; |