diff options
author | Jean-Francois Moine <moinejf@free.fr> | 2008-07-14 08:38:29 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-07-20 06:26:14 -0400 |
commit | 739570bb218bb4607df1f197282561e97a98e54a (patch) | |
tree | 25555dfe5ac873bc96866c486d6f6c1dcabf24f4 /drivers/media/video/gspca/tv8532.c | |
parent | 5b77ae7776183d733ec86727bcc34c52a336afd6 (diff) |
V4L/DVB (8352): gspca: Buffers for USB exchanges cannot be in the stack.
gspca: Protect dq_callback() against simultaneous USB exchanges.
Temporary buffer for USB exchanges added in the device struct.
(all) Use a temporary buffer for all USB exchanges.
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/gspca/tv8532.c')
-rw-r--r-- | drivers/media/video/gspca/tv8532.c | 360 |
1 files changed, 158 insertions, 202 deletions
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c index f9bffd67991e..0b793899095f 100644 --- a/drivers/media/video/gspca/tv8532.c +++ b/drivers/media/video/gspca/tv8532.c | |||
@@ -22,8 +22,8 @@ | |||
22 | 22 | ||
23 | #include "gspca.h" | 23 | #include "gspca.h" |
24 | 24 | ||
25 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) | 25 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) |
26 | static const char version[] = "2.1.5"; | 26 | static const char version[] = "2.1.7"; |
27 | 27 | ||
28 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); | 28 | MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); |
29 | MODULE_DESCRIPTION("TV8532 USB Camera Driver"); | 29 | MODULE_DESCRIPTION("TV8532 USB Camera Driver"); |
@@ -168,63 +168,74 @@ static const __u32 tv_8532_eeprom_data[] = { | |||
168 | 0x0c0509f1, 0 | 168 | 0x0c0509f1, 0 |
169 | }; | 169 | }; |
170 | 170 | ||
171 | static void reg_r(struct usb_device *dev, | 171 | static int reg_r(struct gspca_dev *gspca_dev, |
172 | __u16 index, __u8 *buffer) | 172 | __u16 index) |
173 | { | 173 | { |
174 | usb_control_msg(dev, | 174 | usb_control_msg(gspca_dev->dev, |
175 | usb_rcvctrlpipe(dev, 0), | 175 | usb_rcvctrlpipe(gspca_dev->dev, 0), |
176 | TV8532_REQ_RegRead, | 176 | TV8532_REQ_RegRead, |
177 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 177 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
178 | 0, /* value */ | 178 | 0, /* value */ |
179 | index, buffer, sizeof(__u8), | 179 | index, gspca_dev->usb_buf, 1, |
180 | 500); | 180 | 500); |
181 | return gspca_dev->usb_buf[0]; | ||
181 | } | 182 | } |
182 | 183 | ||
183 | static void reg_w(struct usb_device *dev, | 184 | /* write 1 byte */ |
184 | __u16 index, __u8 *buffer, __u16 length) | 185 | static void reg_w_1(struct gspca_dev *gspca_dev, |
186 | __u16 index, __u8 value) | ||
185 | { | 187 | { |
186 | usb_control_msg(dev, | 188 | gspca_dev->usb_buf[0] = value; |
187 | usb_sndctrlpipe(dev, 0), | 189 | usb_control_msg(gspca_dev->dev, |
190 | usb_sndctrlpipe(gspca_dev->dev, 0), | ||
188 | TV8532_REQ_RegWrite, | 191 | TV8532_REQ_RegWrite, |
189 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 192 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
190 | 0, /* value */ | 193 | 0, /* value */ |
191 | index, buffer, length, 500); | 194 | index, gspca_dev->usb_buf, 1, 500); |
195 | } | ||
196 | |||
197 | /* write 2 bytes */ | ||
198 | static void reg_w_2(struct gspca_dev *gspca_dev, | ||
199 | __u16 index, __u8 val1, __u8 val2) | ||
200 | { | ||
201 | gspca_dev->usb_buf[0] = val1; | ||
202 | gspca_dev->usb_buf[1] = val2; | ||
203 | usb_control_msg(gspca_dev->dev, | ||
204 | usb_sndctrlpipe(gspca_dev->dev, 0), | ||
205 | TV8532_REQ_RegWrite, | ||
206 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
207 | 0, /* value */ | ||
208 | index, gspca_dev->usb_buf, 2, 500); | ||
192 | } | 209 | } |
193 | 210 | ||
194 | static void tv_8532WriteEEprom(struct gspca_dev *gspca_dev) | 211 | static void tv_8532WriteEEprom(struct gspca_dev *gspca_dev) |
195 | { | 212 | { |
196 | int i = 0; | 213 | int i = 0; |
197 | __u8 reg, data0, data1, data2, datacmd; | 214 | __u8 reg, data0, data1, data2; |
198 | struct usb_device *dev = gspca_dev->dev; | ||
199 | 215 | ||
200 | datacmd = 0xb0;; | 216 | reg_w_1(gspca_dev, TV8532_GPIO, 0xb0); |
201 | reg_w(dev, TV8532_GPIO, &datacmd, 1); | 217 | reg_w_1(gspca_dev, TV8532_CTRL, TV8532_CMD_EEprom_Open); |
202 | datacmd = TV8532_CMD_EEprom_Open; | ||
203 | reg_w(dev, TV8532_CTRL, &datacmd, 1); | ||
204 | /* msleep(1); */ | 218 | /* msleep(1); */ |
205 | while (tv_8532_eeprom_data[i]) { | 219 | while (tv_8532_eeprom_data[i]) { |
206 | reg = (tv_8532_eeprom_data[i] & 0xff000000) >> 24; | 220 | reg = (tv_8532_eeprom_data[i] & 0xff000000) >> 24; |
207 | reg_w(dev, TV8532_EEprom_Add, ®, 1); | 221 | reg_w_1(gspca_dev, TV8532_EEprom_Add, reg); |
208 | /* msleep(1); */ | 222 | /* msleep(1); */ |
209 | data0 = (tv_8532_eeprom_data[i] & 0x000000ff); | 223 | data0 = (tv_8532_eeprom_data[i] & 0x000000ff); |
210 | reg_w(dev, TV8532_EEprom_DataL, &data0, 1); | 224 | reg_w_1(gspca_dev, TV8532_EEprom_DataL, data0); |
211 | /* msleep(1); */ | 225 | /* msleep(1); */ |
212 | data1 = (tv_8532_eeprom_data[i] & 0x0000FF00) >> 8; | 226 | data1 = (tv_8532_eeprom_data[i] & 0x0000ff00) >> 8; |
213 | reg_w(dev, TV8532_EEprom_DataM, &data1, 1); | 227 | reg_w_1(gspca_dev, TV8532_EEprom_DataM, data1); |
214 | /* msleep(1); */ | 228 | /* msleep(1); */ |
215 | data2 = (tv_8532_eeprom_data[i] & 0x00FF0000) >> 16; | 229 | data2 = (tv_8532_eeprom_data[i] & 0x00ff0000) >> 16; |
216 | reg_w(dev, TV8532_EEprom_DataH, &data2, 1); | 230 | reg_w_1(gspca_dev, TV8532_EEprom_DataH, data2); |
217 | /* msleep(1); */ | 231 | /* msleep(1); */ |
218 | datacmd = 0; | 232 | reg_w_1(gspca_dev, TV8532_EEprom_Write, 0); |
219 | reg_w(dev, TV8532_EEprom_Write, &datacmd, 1); | ||
220 | /* msleep(10); */ | 233 | /* msleep(10); */ |
221 | i++; | 234 | i++; |
222 | } | 235 | } |
223 | datacmd = i; | 236 | reg_w_1(gspca_dev, TV8532_EEprom_TableLength, i); |
224 | reg_w(dev, TV8532_EEprom_TableLength, &datacmd, 1); | ||
225 | /* msleep(1); */ | 237 | /* msleep(1); */ |
226 | datacmd = TV8532_CMD_EEprom_Close; | 238 | reg_w_1(gspca_dev, TV8532_CTRL, TV8532_CMD_EEprom_Close); |
227 | reg_w(dev, TV8532_CTRL, &datacmd, 1); | ||
228 | msleep(10); | 239 | msleep(10); |
229 | } | 240 | } |
230 | 241 | ||
@@ -250,154 +261,121 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
250 | 261 | ||
251 | static void tv_8532ReadRegisters(struct gspca_dev *gspca_dev) | 262 | static void tv_8532ReadRegisters(struct gspca_dev *gspca_dev) |
252 | { | 263 | { |
253 | struct usb_device *dev = gspca_dev->dev; | ||
254 | __u8 data; | 264 | __u8 data; |
255 | /* __u16 vid, pid; */ | ||
256 | 265 | ||
257 | reg_r(dev, 0x0001, &data); | 266 | data = reg_r(gspca_dev, 0x0001); |
258 | PDEBUG(D_USBI, "register 0x01-> %x", data); | 267 | PDEBUG(D_USBI, "register 0x01-> %x", data); |
259 | reg_r(dev, 0x0002, &data); | 268 | data = reg_r(gspca_dev, 0x0002); |
260 | PDEBUG(D_USBI, "register 0x02-> %x", data); | 269 | PDEBUG(D_USBI, "register 0x02-> %x", data); |
261 | reg_r(dev, TV8532_ADWIDTH_L, &data); | 270 | reg_r(gspca_dev, TV8532_ADWIDTH_L); |
262 | reg_r(dev, TV8532_ADWIDTH_H, &data); | 271 | reg_r(gspca_dev, TV8532_ADWIDTH_H); |
263 | reg_r(dev, TV8532_QUANT_COMP, &data); | 272 | reg_r(gspca_dev, TV8532_QUANT_COMP); |
264 | reg_r(dev, TV8532_MODE_PACKET, &data); | 273 | reg_r(gspca_dev, TV8532_MODE_PACKET); |
265 | reg_r(dev, TV8532_SETCLK, &data); | 274 | reg_r(gspca_dev, TV8532_SETCLK); |
266 | reg_r(dev, TV8532_POINT_L, &data); | 275 | reg_r(gspca_dev, TV8532_POINT_L); |
267 | reg_r(dev, TV8532_POINT_H, &data); | 276 | reg_r(gspca_dev, TV8532_POINT_H); |
268 | reg_r(dev, TV8532_POINTB_L, &data); | 277 | reg_r(gspca_dev, TV8532_POINTB_L); |
269 | reg_r(dev, TV8532_POINTB_H, &data); | 278 | reg_r(gspca_dev, TV8532_POINTB_H); |
270 | reg_r(dev, TV8532_BUDGET_L, &data); | 279 | reg_r(gspca_dev, TV8532_BUDGET_L); |
271 | reg_r(dev, TV8532_BUDGET_H, &data); | 280 | reg_r(gspca_dev, TV8532_BUDGET_H); |
272 | reg_r(dev, TV8532_VID_L, &data); | 281 | reg_r(gspca_dev, TV8532_VID_L); |
273 | reg_r(dev, TV8532_VID_H, &data); | 282 | reg_r(gspca_dev, TV8532_VID_H); |
274 | reg_r(dev, TV8532_PID_L, &data); | 283 | reg_r(gspca_dev, TV8532_PID_L); |
275 | reg_r(dev, TV8532_PID_H, &data); | 284 | reg_r(gspca_dev, TV8532_PID_H); |
276 | reg_r(dev, TV8532_DeviceID, &data); | 285 | reg_r(gspca_dev, TV8532_DeviceID); |
277 | reg_r(dev, TV8532_AD_COLBEGIN_L, &data); | 286 | reg_r(gspca_dev, TV8532_AD_COLBEGIN_L); |
278 | reg_r(dev, TV8532_AD_COLBEGIN_H, &data); | 287 | reg_r(gspca_dev, TV8532_AD_COLBEGIN_H); |
279 | reg_r(dev, TV8532_AD_ROWBEGIN_L, &data); | 288 | reg_r(gspca_dev, TV8532_AD_ROWBEGIN_L); |
280 | reg_r(dev, TV8532_AD_ROWBEGIN_H, &data); | 289 | reg_r(gspca_dev, TV8532_AD_ROWBEGIN_H); |
281 | } | 290 | } |
282 | 291 | ||
283 | static void tv_8532_setReg(struct gspca_dev *gspca_dev) | 292 | static void tv_8532_setReg(struct gspca_dev *gspca_dev) |
284 | { | 293 | { |
285 | struct usb_device *dev = gspca_dev->dev; | 294 | reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_L, |
286 | __u8 data; | 295 | ADCBEGINL); /* 0x10 */ |
287 | __u8 value[2] = { 0, 0 }; | 296 | reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_H, |
288 | 297 | ADCBEGINH); /* also digital gain */ | |
289 | data = ADCBEGINL; | 298 | reg_w_1(gspca_dev, TV8532_PART_CTRL, |
290 | reg_w(dev, TV8532_AD_COLBEGIN_L, &data, 1); /* 0x10 */ | 299 | TV8532_CMD_UPDATE); /* 0x00<-0x84 */ |
291 | data = ADCBEGINH; /* also digital gain */ | 300 | |
292 | reg_w(dev, TV8532_AD_COLBEGIN_H, &data, 1); | 301 | reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0a); |
293 | data = TV8532_CMD_UPDATE; | ||
294 | reg_w(dev, TV8532_PART_CTRL, &data, 1); /* 0x00<-0x84 */ | ||
295 | |||
296 | data = 0x0a; | ||
297 | reg_w(dev, TV8532_GPIO_OE, &data, 1); | ||
298 | /******************************************************/ | 302 | /******************************************************/ |
299 | data = ADHEIGHL; | 303 | reg_w_1(gspca_dev, TV8532_ADHEIGHT_L, ADHEIGHL); /* 0e */ |
300 | reg_w(dev, TV8532_ADHEIGHT_L, &data, 1); /* 0e */ | 304 | reg_w_1(gspca_dev, TV8532_ADHEIGHT_H, ADHEIGHH); /* 0f */ |
301 | data = ADHEIGHH; | 305 | reg_w_2(gspca_dev, TV8532_EXPOSURE, |
302 | reg_w(dev, TV8532_ADHEIGHT_H, &data, 1); /* 0f */ | 306 | EXPOL, EXPOH); /* 350d 0x014c; 1c */ |
303 | value[0] = EXPOL; | 307 | reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_L, |
304 | value[1] = EXPOH; /* 350d 0x014c; */ | 308 | ADCBEGINL); /* 0x10 */ |
305 | reg_w(dev, TV8532_EXPOSURE, value, 2); /* 1c */ | 309 | reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_H, |
306 | data = ADCBEGINL; | 310 | ADCBEGINH); /* also digital gain */ |
307 | reg_w(dev, TV8532_AD_COLBEGIN_L, &data, 1); /* 0x10 */ | 311 | reg_w_1(gspca_dev, TV8532_AD_ROWBEGIN_L, |
308 | data = ADCBEGINH; /* also digital gain */ | 312 | ADRBEGINL); /* 0x14 */ |
309 | reg_w(dev, TV8532_AD_COLBEGIN_H, &data, 1); | 313 | |
310 | data = ADRBEGINL; | 314 | reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x00); /* 0x91 */ |
311 | reg_w(dev, TV8532_AD_ROWBEGIN_L, &data, 1); /* 0x14 */ | 315 | reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x02); /* 0x94 */ |
312 | 316 | ||
313 | data = 0x00; | 317 | reg_w_1(gspca_dev, TV8532_CTRL, |
314 | reg_w(dev, TV8532_AD_SLOPE, &data, 1); /* 0x91 */ | 318 | TV8532_CMD_EEprom_Close); /* 0x01 */ |
315 | data = 0x02; | 319 | |
316 | reg_w(dev, TV8532_AD_BITCTRL, &data, 1); /* 0x94 */ | 320 | reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x00); /* 0x91 */ |
317 | 321 | reg_w_1(gspca_dev, TV8532_PART_CTRL, | |
318 | 322 | TV8532_CMD_UPDATE); /* 0x00<-0x84 */ | |
319 | data = TV8532_CMD_EEprom_Close; | ||
320 | reg_w(dev, TV8532_CTRL, &data, 1); /* 0x01 */ | ||
321 | |||
322 | data = 0x00; | ||
323 | reg_w(dev, TV8532_AD_SLOPE, &data, 1); /* 0x91 */ | ||
324 | data = TV8532_CMD_UPDATE; | ||
325 | reg_w(dev, TV8532_PART_CTRL, &data, 1); /* 0x00<-0x84 */ | ||
326 | } | 323 | } |
327 | 324 | ||
328 | static void tv_8532_PollReg(struct gspca_dev *gspca_dev) | 325 | static void tv_8532_PollReg(struct gspca_dev *gspca_dev) |
329 | { | 326 | { |
330 | struct usb_device *dev = gspca_dev->dev; | ||
331 | __u8 data; | ||
332 | int i; | 327 | int i; |
333 | 328 | ||
334 | /* strange polling from tgc */ | 329 | /* strange polling from tgc */ |
335 | for (i = 0; i < 10; i++) { | 330 | for (i = 0; i < 10; i++) { |
336 | data = TESTCLK; /* 0x48; //0x08; */ | 331 | reg_w_1(gspca_dev, TV8532_SETCLK, |
337 | reg_w(dev, TV8532_SETCLK, &data, 1); /* 0x2c */ | 332 | TESTCLK); /* 0x48; //0x08; 0x2c */ |
338 | data = TV8532_CMD_UPDATE; | 333 | reg_w_1(gspca_dev, TV8532_PART_CTRL, TV8532_CMD_UPDATE); |
339 | reg_w(dev, TV8532_PART_CTRL, &data, 1); | 334 | reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */ |
340 | data = 0x01; | ||
341 | reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */ | ||
342 | } | 335 | } |
343 | } | 336 | } |
344 | 337 | ||
345 | /* this function is called at open time */ | 338 | /* this function is called at open time */ |
346 | static int sd_open(struct gspca_dev *gspca_dev) | 339 | static int sd_open(struct gspca_dev *gspca_dev) |
347 | { | 340 | { |
348 | struct usb_device *dev = gspca_dev->dev; | 341 | reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32); |
349 | __u8 data; | 342 | reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00); |
350 | __u8 dataStart; | ||
351 | __u8 value[2]; | ||
352 | |||
353 | data = 0x32; | ||
354 | reg_w(dev, TV8532_AD_SLOPE, &data, 1); | ||
355 | data = 0; | ||
356 | reg_w(dev, TV8532_AD_BITCTRL, &data, 1); | ||
357 | tv_8532ReadRegisters(gspca_dev); | 343 | tv_8532ReadRegisters(gspca_dev); |
358 | data = 0x0b; | 344 | reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); |
359 | reg_w(dev, TV8532_GPIO_OE, &data, 1); | 345 | reg_w_2(gspca_dev, TV8532_ADHEIGHT_L, ADHEIGHL, |
360 | value[0] = ADHEIGHL; | 346 | ADHEIGHH); /* 401d 0x0169; 0e */ |
361 | value[1] = ADHEIGHH; /* 401d 0x0169; */ | 347 | reg_w_2(gspca_dev, TV8532_EXPOSURE, EXPOL, |
362 | reg_w(dev, TV8532_ADHEIGHT_L, value, 2); /* 0e */ | 348 | EXPOH); /* 350d 0x014c; 1c */ |
363 | value[0] = EXPOL; | 349 | reg_w_1(gspca_dev, TV8532_ADWIDTH_L, ADWIDTHL); /* 0x20; 0x0c */ |
364 | value[1] = EXPOH; /* 350d 0x014c; */ | 350 | reg_w_1(gspca_dev, TV8532_ADWIDTH_H, ADWIDTHH); /* 0x0d */ |
365 | reg_w(dev, TV8532_EXPOSURE, value, 2); /* 1c */ | ||
366 | data = ADWIDTHL; /* 0x20; */ | ||
367 | reg_w(dev, TV8532_ADWIDTH_L, &data, 1); /* 0x0c */ | ||
368 | data = ADWIDTHH; | ||
369 | reg_w(dev, TV8532_ADWIDTH_H, &data, 1); /* 0x0d */ | ||
370 | 351 | ||
371 | /*******************************************************************/ | 352 | /*******************************************************************/ |
372 | data = TESTCOMP; /* 0x72 compressed mode */ | 353 | reg_w_1(gspca_dev, TV8532_QUANT_COMP, |
373 | reg_w(dev, TV8532_QUANT_COMP, &data, 1); /* 0x28 */ | 354 | TESTCOMP); /* 0x72 compressed mode 0x28 */ |
374 | data = TESTLINE; /* 0x84; // CIF | 4 packet */ | 355 | reg_w_1(gspca_dev, TV8532_MODE_PACKET, |
375 | reg_w(dev, TV8532_MODE_PACKET, &data, 1); /* 0x29 */ | 356 | TESTLINE); /* 0x84; // CIF | 4 packet 0x29 */ |
376 | 357 | ||
377 | /************************************************/ | 358 | /************************************************/ |
378 | data = TESTCLK; /* 0x48; //0x08; */ | 359 | reg_w_1(gspca_dev, TV8532_SETCLK, |
379 | reg_w(dev, TV8532_SETCLK, &data, 1); /* 0x2c */ | 360 | TESTCLK); /* 0x48; //0x08; 0x2c */ |
380 | data = TESTPTL; /* 0x38; */ | 361 | reg_w_1(gspca_dev, TV8532_POINT_L, |
381 | reg_w(dev, TV8532_POINT_L, &data, 1); /* 0x2d */ | 362 | TESTPTL); /* 0x38; 0x2d */ |
382 | data = TESTPTH; /* 0x04; */ | 363 | reg_w_1(gspca_dev, TV8532_POINT_H, |
383 | reg_w(dev, TV8532_POINT_H, &data, 1); /* 0x2e */ | 364 | TESTPTH); /* 0x04; 0x2e */ |
384 | dataStart = TESTPTBL; /* 0x04; */ | 365 | reg_w_1(gspca_dev, TV8532_POINTB_L, |
385 | reg_w(dev, TV8532_POINTB_L, &dataStart, 1); /* 0x2f */ | 366 | TESTPTBL); /* 0x04; 0x2f */ |
386 | data = TESTPTBH; /* 0x04; */ | 367 | reg_w_1(gspca_dev, TV8532_POINTB_H, |
387 | reg_w(dev, TV8532_POINTB_H, &data, 1); /* 0x30 */ | 368 | TESTPTBH); /* 0x04; 0x30 */ |
388 | data = TV8532_CMD_UPDATE; | 369 | reg_w_1(gspca_dev, TV8532_PART_CTRL, |
389 | reg_w(dev, TV8532_PART_CTRL, &data, 1); /* 0x00<-0x84 */ | 370 | TV8532_CMD_UPDATE); /* 0x00<-0x84 */ |
390 | /*************************************************/ | 371 | /*************************************************/ |
391 | data = 0x01; | 372 | reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */ |
392 | reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */ | ||
393 | msleep(200); | 373 | msleep(200); |
394 | data = 0x00; | 374 | reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */ |
395 | reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */ | ||
396 | /*************************************************/ | 375 | /*************************************************/ |
397 | tv_8532_setReg(gspca_dev); | 376 | tv_8532_setReg(gspca_dev); |
398 | /*************************************************/ | 377 | /*************************************************/ |
399 | data = 0x0b; | 378 | reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); |
400 | reg_w(dev, TV8532_GPIO_OE, &data, 1); | ||
401 | /*************************************************/ | 379 | /*************************************************/ |
402 | tv_8532_setReg(gspca_dev); | 380 | tv_8532_setReg(gspca_dev); |
403 | /*************************************************/ | 381 | /*************************************************/ |
@@ -408,94 +386,72 @@ static int sd_open(struct gspca_dev *gspca_dev) | |||
408 | static void setbrightness(struct gspca_dev *gspca_dev) | 386 | static void setbrightness(struct gspca_dev *gspca_dev) |
409 | { | 387 | { |
410 | struct sd *sd = (struct sd *) gspca_dev; | 388 | struct sd *sd = (struct sd *) gspca_dev; |
411 | __u8 value[2]; | ||
412 | __u8 data; | ||
413 | int brightness = sd->brightness; | 389 | int brightness = sd->brightness; |
414 | 390 | ||
415 | value[1] = (brightness >> 8) & 0xff; | 391 | reg_w_2(gspca_dev, TV8532_EXPOSURE, |
416 | value[0] = (brightness) & 0xff; | 392 | brightness >> 8, brightness); /* 1c */ |
417 | reg_w(gspca_dev->dev, TV8532_EXPOSURE, value, 2); /* 1c */ | 393 | reg_w_1(gspca_dev, TV8532_PART_CTRL, TV8532_CMD_UPDATE); |
418 | data = TV8532_CMD_UPDATE; | ||
419 | reg_w(gspca_dev->dev, TV8532_PART_CTRL, &data, 1); | ||
420 | } | 394 | } |
421 | 395 | ||
422 | /* -- start the camera -- */ | 396 | /* -- start the camera -- */ |
423 | static void sd_start(struct gspca_dev *gspca_dev) | 397 | static void sd_start(struct gspca_dev *gspca_dev) |
424 | { | 398 | { |
425 | struct usb_device *dev = gspca_dev->dev; | 399 | reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32); |
426 | __u8 data; | 400 | reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00); |
427 | __u8 value[2]; | ||
428 | |||
429 | data = 0x32; | ||
430 | reg_w(dev, TV8532_AD_SLOPE, &data, 1); | ||
431 | data = 0; | ||
432 | reg_w(dev, TV8532_AD_BITCTRL, &data, 1); | ||
433 | tv_8532ReadRegisters(gspca_dev); | 401 | tv_8532ReadRegisters(gspca_dev); |
434 | data = 0x0b; | 402 | reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); |
435 | reg_w(dev, TV8532_GPIO_OE, &data, 1); | 403 | reg_w_2(gspca_dev, TV8532_ADHEIGHT_L, |
436 | value[0] = ADHEIGHL; | 404 | ADHEIGHL, ADHEIGHH); /* 401d 0x0169; 0e */ |
437 | value[1] = ADHEIGHH; /* 401d 0x0169; */ | 405 | /* reg_w_2(gspca_dev, TV8532_EXPOSURE, |
438 | reg_w(dev, TV8532_ADHEIGHT_L, value, 2); /* 0e */ | 406 | EXPOL, EXPOH); * 350d 0x014c; 1c */ |
439 | /* value[0] = EXPOL; value[1] =EXPOH; * 350d 0x014c; */ | ||
440 | /* reg_w(dev,TV8532_REQ_RegWrite,0,TV8532_EXPOSURE,value,2); * 1c */ | ||
441 | setbrightness(gspca_dev); | 407 | setbrightness(gspca_dev); |
442 | 408 | ||
443 | data = ADWIDTHL; /* 0x20; */ | 409 | reg_w_1(gspca_dev, TV8532_ADWIDTH_L, ADWIDTHL); /* 0x20; 0x0c */ |
444 | reg_w(dev, TV8532_ADWIDTH_L, &data, 1); /* 0x0c */ | 410 | reg_w_1(gspca_dev, TV8532_ADWIDTH_H, ADWIDTHH); /* 0x0d */ |
445 | data = ADWIDTHH; | ||
446 | reg_w(dev, TV8532_ADWIDTH_H, &data, 1); /* 0x0d */ | ||
447 | 411 | ||
448 | /************************************************/ | 412 | /************************************************/ |
449 | data = TESTCOMP; /* 0x72 compressed mode */ | 413 | reg_w_1(gspca_dev, TV8532_QUANT_COMP, |
450 | reg_w(dev, TV8532_QUANT_COMP, &data, 1); /* 0x28 */ | 414 | TESTCOMP); /* 0x72 compressed mode 0x28 */ |
451 | if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { | 415 | if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { |
452 | /* 176x144 */ | 416 | /* 176x144 */ |
453 | data = QCIFLINE; /* 0x84; // CIF | 4 packet */ | 417 | reg_w_1(gspca_dev, TV8532_MODE_PACKET, |
454 | reg_w(dev, TV8532_MODE_PACKET, &data, 1); /* 0x29 */ | 418 | QCIFLINE); /* 0x84; // CIF | 4 packet 0x29 */ |
455 | } else { | 419 | } else { |
456 | /* 352x288 */ | 420 | /* 352x288 */ |
457 | data = TESTLINE; /* 0x84; // CIF | 4 packet */ | 421 | reg_w_1(gspca_dev, TV8532_MODE_PACKET, |
458 | reg_w(dev, TV8532_MODE_PACKET, &data, 1); /* 0x29 */ | 422 | TESTLINE); /* 0x84; // CIF | 4 packet 0x29 */ |
459 | } | 423 | } |
460 | /************************************************/ | 424 | /************************************************/ |
461 | data = TESTCLK; /* 0x48; //0x08; */ | 425 | reg_w_1(gspca_dev, TV8532_SETCLK, |
462 | reg_w(dev, TV8532_SETCLK, &data, 1); /* 0x2c */ | 426 | TESTCLK); /* 0x48; //0x08; 0x2c */ |
463 | data = TESTPTL; /* 0x38; */ | 427 | reg_w_1(gspca_dev, TV8532_POINT_L, |
464 | reg_w(dev, TV8532_POINT_L, &data, 1); /* 0x2d */ | 428 | TESTPTL); /* 0x38; 0x2d */ |
465 | data = TESTPTH; /* 0x04; */ | 429 | reg_w_1(gspca_dev, TV8532_POINT_H, |
466 | reg_w(dev, TV8532_POINT_H, &data, 1); /* 0x2e */ | 430 | TESTPTH); /* 0x04; 0x2e */ |
467 | data = TESTPTBL; /* 0x04; */ | 431 | reg_w_1(gspca_dev, TV8532_POINTB_L, |
468 | reg_w(dev, TV8532_POINTB_L, &data, 1); /* 0x2f */ | 432 | TESTPTBL); /* 0x04; 0x2f */ |
469 | data = TESTPTBH; /* 0x04; */ | 433 | reg_w_1(gspca_dev, TV8532_POINTB_H, |
470 | reg_w(dev, TV8532_POINTB_H, &data, 1); /* 0x30 */ | 434 | TESTPTBH); /* 0x04; 0x30 */ |
471 | data = TV8532_CMD_UPDATE; | 435 | reg_w_1(gspca_dev, TV8532_PART_CTRL, |
472 | reg_w(dev, TV8532_PART_CTRL, &data, 1); /* 0x00<-0x84 */ | 436 | TV8532_CMD_UPDATE); /* 0x00<-0x84 */ |
473 | /************************************************/ | 437 | /************************************************/ |
474 | data = 0x01; | 438 | reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */ |
475 | reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */ | ||
476 | msleep(200); | 439 | msleep(200); |
477 | data = 0x00; | 440 | reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */ |
478 | reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */ | ||
479 | /************************************************/ | 441 | /************************************************/ |
480 | tv_8532_setReg(gspca_dev); | 442 | tv_8532_setReg(gspca_dev); |
481 | /************************************************/ | 443 | /************************************************/ |
482 | data = 0x0b; | 444 | reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); |
483 | reg_w(dev, TV8532_GPIO_OE, &data, 1); | ||
484 | /************************************************/ | 445 | /************************************************/ |
485 | tv_8532_setReg(gspca_dev); | 446 | tv_8532_setReg(gspca_dev); |
486 | /************************************************/ | 447 | /************************************************/ |
487 | tv_8532_PollReg(gspca_dev); | 448 | tv_8532_PollReg(gspca_dev); |
488 | data = 0x00; | 449 | reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */ |
489 | reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */ | ||
490 | } | 450 | } |
491 | 451 | ||
492 | static void sd_stopN(struct gspca_dev *gspca_dev) | 452 | static void sd_stopN(struct gspca_dev *gspca_dev) |
493 | { | 453 | { |
494 | struct usb_device *dev = gspca_dev->dev; | 454 | reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); |
495 | __u8 data; | ||
496 | |||
497 | data = 0x0b; | ||
498 | reg_w(dev, TV8532_GPIO_OE, &data, 1); | ||
499 | } | 455 | } |
500 | 456 | ||
501 | static void sd_stop0(struct gspca_dev *gspca_dev) | 457 | static void sd_stop0(struct gspca_dev *gspca_dev) |