diff options
author | Theodore Kilgore <kilgota@banach.math.auburn.edu> | 2010-01-14 10:07:18 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-02-26 13:10:40 -0500 |
commit | ed9885aa8145d0cd531ac53d1456a6b3d238150c (patch) | |
tree | a760d602f069c9364a27aa41da2864ce29258d87 /drivers/media/video/gspca/sq905c.c | |
parent | 127f548dbcdb561a7bf94578804abca0eccf7e4b (diff) |
V4L/DVB (14006): gscpa_sq905c: Better detection of CIF resolution cameras
gscpa_sq905c: Better detection of CIF resolution cameras
Signed-off-by: Theodore Kilgore <kilgota@banach.math.auburn.edu>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/gspca/sq905c.c')
-rw-r--r-- | drivers/media/video/gspca/sq905c.c | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c index d70b156872d6..bbfaf8361f65 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 i, 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; |