1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
35
36#define W9968CF_I2C_BUS_DELAY 4
37
38#define Y_QUANTABLE (&sd->jpeg_hdr[JPEG_QT0_OFFSET])
39#define UV_QUANTABLE (&sd->jpeg_hdr[JPEG_QT1_OFFSET])
40
41static const struct v4l2_pix_format w9968cf_vga_mode[] = {
42 {160, 120, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
43 .bytesperline = 160 * 2,
44 .sizeimage = 160 * 120 * 2,
45 .colorspace = V4L2_COLORSPACE_JPEG},
46 {176, 144, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
47 .bytesperline = 176 * 2,
48 .sizeimage = 176 * 144 * 2,
49 .colorspace = V4L2_COLORSPACE_JPEG},
50 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
51 .bytesperline = 320 * 2,
52 .sizeimage = 320 * 240 * 2,
53 .colorspace = V4L2_COLORSPACE_JPEG},
54 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
55 .bytesperline = 352 * 2,
56 .sizeimage = 352 * 288 * 2,
57 .colorspace = V4L2_COLORSPACE_JPEG},
58 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
59 .bytesperline = 640 * 2,
60 .sizeimage = 640 * 480 * 2,
61 .colorspace = V4L2_COLORSPACE_JPEG},
62};
63
64static void reg_w(struct sd *sd, u16 index, u16 value);
65
66
67
68
69
70static void w9968cf_write_fsb(struct sd *sd, u16* data)
71{
72 struct usb_device *udev = sd->gspca_dev.dev;
73 u16 value;
74 int ret;
75
76 if (sd->gspca_dev.usb_err < 0)
77 return;
78
79 value = *data++;
80 memcpy(sd->gspca_dev.usb_buf, data, 6);
81
82
83 udelay(150);
84 ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
85 USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
86 value, 0x06, sd->gspca_dev.usb_buf, 6, 500);
87 if (ret < 0) {
88 pr_err("Write FSB registers failed (%d)\n", ret);
89 sd->gspca_dev.usb_err = ret;
90 }
91}
92
93
94
95
96
97static void w9968cf_write_sb(struct sd *sd, u16 value)
98{
99 int ret;
100
101 if (sd->gspca_dev.usb_err < 0)
102 return;
103
104
105 udelay(150);
106
107
108
109 ret = usb_control_msg(sd->gspca_dev.dev,
110 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
111 0,
112 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
113 value, 0x01, NULL, 0, 500);
114
115 udelay(W9968CF_I2C_BUS_DELAY);
116
117 if (ret < 0) {
118 pr_err("Write SB reg [01] %04x failed\n", value);
119 sd->gspca_dev.usb_err = ret;
120 }
121}
122
123
124
125
126
127static int w9968cf_read_sb(struct sd *sd)
128{
129 int ret;
130
131 if (sd->gspca_dev.usb_err < 0)
132 return -1;
133
134
135 udelay(150);
136
137
138
139 ret = usb_control_msg(sd->gspca_dev.dev,
140 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
141 1,
142 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
143 0, 0x01, sd->gspca_dev.usb_buf, 2, 500);
144 if (ret >= 0) {
145 ret = sd->gspca_dev.usb_buf[0] |
146 (sd->gspca_dev.usb_buf[1] << 8);
147 } else {
148 pr_err("Read SB reg [01] failed\n");
149 sd->gspca_dev.usb_err = ret;
150 }
151
152 udelay(W9968CF_I2C_BUS_DELAY);
153
154 return ret;
155}
156
157
158
159
160
161
162static void w9968cf_upload_quantizationtables(struct sd *sd)
163{
164 u16 a, b;
165 int i, j;
166
167 reg_w(sd, 0x39, 0x0010);
168
169 for (i = 0, j = 0; i < 32; i++, j += 2) {
170 a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j + 1]) << 8);
171 b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j + 1]) << 8);
172 reg_w(sd, 0x40 + i, a);
173 reg_w(sd, 0x60 + i, b);
174 }
175 reg_w(sd, 0x39, 0x0012);
176}
177
178
179
180
181
182
183
184
185
186static void w9968cf_smbus_start(struct sd *sd)
187{
188 w9968cf_write_sb(sd, 0x0011);
189 w9968cf_write_sb(sd, 0x0010);
190}
191
192static void w9968cf_smbus_stop(struct sd *sd)
193{
194 w9968cf_write_sb(sd, 0x0010);
195 w9968cf_write_sb(sd, 0x0011);
196 w9968cf_write_sb(sd, 0x0013);
197}
198
199static void w9968cf_smbus_write_byte(struct sd *sd, u8 v)
200{
201 u8 bit;
202 int sda;
203
204 for (bit = 0 ; bit < 8 ; bit++) {
205 sda = (v & 0x80) ? 2 : 0;
206 v <<= 1;
207
208 w9968cf_write_sb(sd, 0x10 | sda);
209
210 w9968cf_write_sb(sd, 0x11 | sda);
211
212 w9968cf_write_sb(sd, 0x10 | sda);
213 }
214}
215
216static void w9968cf_smbus_read_byte(struct sd *sd, u8 *v)
217{
218 u8 bit;
219
220
221
222 *v = 0;
223 for (bit = 0 ; bit < 8 ; bit++) {
224 *v <<= 1;
225
226 w9968cf_write_sb(sd, 0x0013);
227 *v |= (w9968cf_read_sb(sd) & 0x0008) ? 1 : 0;
228
229 w9968cf_write_sb(sd, 0x0012);
230 }
231}
232
233static void w9968cf_smbus_write_nack(struct sd *sd)
234{
235
236
237 w9968cf_write_sb(sd, 0x0013);
238 w9968cf_write_sb(sd, 0x0012);
239}
240
241static void w9968cf_smbus_read_ack(struct sd *sd)
242{
243 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
244 int sda;
245
246
247 w9968cf_write_sb(sd, 0x0012);
248 w9968cf_write_sb(sd, 0x0013);
249 sda = w9968cf_read_sb(sd);
250 w9968cf_write_sb(sd, 0x0012);
251 if (sda >= 0 && (sda & 0x08)) {
252 PDEBUG(D_USBI, "Did not receive i2c ACK");
253 sd->gspca_dev.usb_err = -EIO;
254 }
255}
256
257
258static void w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value)
259{
260 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
261 u16* data = (u16 *)sd->gspca_dev.usb_buf;
262
263 data[0] = 0x082f | ((sd->sensor_addr & 0x80) ? 0x1500 : 0x0);
264 data[0] |= (sd->sensor_addr & 0x40) ? 0x4000 : 0x0;
265 data[1] = 0x2082 | ((sd->sensor_addr & 0x40) ? 0x0005 : 0x0);
266 data[1] |= (sd->sensor_addr & 0x20) ? 0x0150 : 0x0;
267 data[1] |= (sd->sensor_addr & 0x10) ? 0x5400 : 0x0;
268 data[2] = 0x8208 | ((sd->sensor_addr & 0x08) ? 0x0015 : 0x0);
269 data[2] |= (sd->sensor_addr & 0x04) ? 0x0540 : 0x0;
270 data[2] |= (sd->sensor_addr & 0x02) ? 0x5000 : 0x0;
271 data[3] = 0x1d20 | ((sd->sensor_addr & 0x02) ? 0x0001 : 0x0);
272 data[3] |= (sd->sensor_addr & 0x01) ? 0x0054 : 0x0;
273
274 w9968cf_write_fsb(sd, data);
275
276 data[0] = 0x8208 | ((reg & 0x80) ? 0x0015 : 0x0);
277 data[0] |= (reg & 0x40) ? 0x0540 : 0x0;
278 data[0] |= (reg & 0x20) ? 0x5000 : 0x0;
279 data[1] = 0x0820 | ((reg & 0x20) ? 0x0001 : 0x0);
280 data[1] |= (reg & 0x10) ? 0x0054 : 0x0;
281 data[1] |= (reg & 0x08) ? 0x1500 : 0x0;
282 data[1] |= (reg & 0x04) ? 0x4000 : 0x0;
283 data[2] = 0x2082 | ((reg & 0x04) ? 0x0005 : 0x0);
284 data[2] |= (reg & 0x02) ? 0x0150 : 0x0;
285 data[2] |= (reg & 0x01) ? 0x5400 : 0x0;
286 data[3] = 0x001d;
287
288 w9968cf_write_fsb(sd, data);
289
290 data[0] = 0x8208 | ((value & 0x80) ? 0x0015 : 0x0);
291 data[0] |= (value & 0x40) ? 0x0540 : 0x0;
292 data[0] |= (value & 0x20) ? 0x5000 : 0x0;
293 data[1] = 0x0820 | ((value & 0x20) ? 0x0001 : 0x0);
294 data[1] |= (value & 0x10) ? 0x0054 : 0x0;
295 data[1] |= (value & 0x08) ? 0x1500 : 0x0;
296 data[1] |= (value & 0x04) ? 0x4000 : 0x0;
297 data[2] = 0x2082 | ((value & 0x04) ? 0x0005 : 0x0);
298 data[2] |= (value & 0x02) ? 0x0150 : 0x0;
299 data[2] |= (value & 0x01) ? 0x5400 : 0x0;
300 data[3] = 0xfe1d;
301
302 w9968cf_write_fsb(sd, data);
303
304 PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
305}
306
307
308static int w9968cf_i2c_r(struct sd *sd, u8 reg)
309{
310 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
311 int ret = 0;
312 u8 value;
313
314
315 w9968cf_write_sb(sd, 0x0013);
316
317 w9968cf_smbus_start(sd);
318 w9968cf_smbus_write_byte(sd, sd->sensor_addr);
319 w9968cf_smbus_read_ack(sd);
320 w9968cf_smbus_write_byte(sd, reg);
321 w9968cf_smbus_read_ack(sd);
322 w9968cf_smbus_stop(sd);
323 w9968cf_smbus_start(sd);
324 w9968cf_smbus_write_byte(sd, sd->sensor_addr + 1);
325 w9968cf_smbus_read_ack(sd);
326 w9968cf_smbus_read_byte(sd, &value);
327
328
329
330 w9968cf_smbus_write_nack(sd);
331 w9968cf_smbus_stop(sd);
332
333
334 w9968cf_write_sb(sd, 0x0030);
335
336 if (sd->gspca_dev.usb_err >= 0) {
337 ret = value;
338 PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
339 } else
340 PERR("i2c read [0x%02x] failed", reg);
341
342 return ret;
343}
344
345
346
347
348
349static void w9968cf_configure(struct sd *sd)
350{
351 reg_w(sd, 0x00, 0xff00);
352 reg_w(sd, 0x00, 0xbf17);
353 reg_w(sd, 0x00, 0xbf10);
354 reg_w(sd, 0x01, 0x0010);
355 reg_w(sd, 0x01, 0x0000);
356 reg_w(sd, 0x01, 0x0010);
357 reg_w(sd, 0x01, 0x0030);
358
359 sd->stopped = 1;
360}
361
362static void w9968cf_init(struct sd *sd)
363{
364 unsigned long hw_bufsize = sd->sif ? (352 * 288 * 2) : (640 * 480 * 2),
365 y0 = 0x0000,
366 u0 = y0 + hw_bufsize / 2,
367 v0 = u0 + hw_bufsize / 4,
368 y1 = v0 + hw_bufsize / 4,
369 u1 = y1 + hw_bufsize / 2,
370 v1 = u1 + hw_bufsize / 4;
371
372 reg_w(sd, 0x00, 0xff00);
373 reg_w(sd, 0x00, 0xbf10);
374
375 reg_w(sd, 0x03, 0x405d);
376 reg_w(sd, 0x04, 0x0030);
377
378 reg_w(sd, 0x20, y0 & 0xffff);
379 reg_w(sd, 0x21, y0 >> 16);
380 reg_w(sd, 0x24, u0 & 0xffff);
381 reg_w(sd, 0x25, u0 >> 16);
382 reg_w(sd, 0x28, v0 & 0xffff);
383 reg_w(sd, 0x29, v0 >> 16);
384
385 reg_w(sd, 0x22, y1 & 0xffff);
386 reg_w(sd, 0x23, y1 >> 16);
387 reg_w(sd, 0x26, u1 & 0xffff);
388 reg_w(sd, 0x27, u1 >> 16);
389 reg_w(sd, 0x2a, v1 & 0xffff);
390 reg_w(sd, 0x2b, v1 >> 16);
391
392 reg_w(sd, 0x32, y1 & 0xffff);
393 reg_w(sd, 0x33, y1 >> 16);
394
395 reg_w(sd, 0x34, y1 & 0xffff);
396 reg_w(sd, 0x35, y1 >> 16);
397
398 reg_w(sd, 0x36, 0x0000);
399 reg_w(sd, 0x37, 0x0804);
400 reg_w(sd, 0x38, 0x0000);
401 reg_w(sd, 0x3f, 0x0000);
402}
403
404static void w9968cf_set_crop_window(struct sd *sd)
405{
406 int start_cropx, start_cropy, x, y, fw, fh, cw, ch,
407 max_width, max_height;
408
409 if (sd->sif) {
410 max_width = 352;
411 max_height = 288;
412 } else {
413 max_width = 640;
414 max_height = 480;
415 }
416
417 if (sd->sensor == SEN_OV7620) {
418
419
420
421
422
423
424
425 if (sd->freq->val == 1) {
426 start_cropx = 277;
427 start_cropy = 37;
428 } else {
429 start_cropx = 105;
430 start_cropy = 37;
431 }
432 } else {
433 start_cropx = 320;
434 start_cropy = 35;
435 }
436
437
438 #define SC(x) ((x) << 10)
439
440
441 fw = SC(sd->gspca_dev.pixfmt.width) / max_width;
442 fh = SC(sd->gspca_dev.pixfmt.height) / max_height;
443
444 cw = (fw >= fh) ? max_width : SC(sd->gspca_dev.pixfmt.width) / fh;
445 ch = (fw >= fh) ? SC(sd->gspca_dev.pixfmt.height) / fw : max_height;
446
447 sd->sensor_width = max_width;
448 sd->sensor_height = max_height;
449
450 x = (max_width - cw) / 2;
451 y = (max_height - ch) / 2;
452
453 reg_w(sd, 0x10, start_cropx + x);
454 reg_w(sd, 0x11, start_cropy + y);
455 reg_w(sd, 0x12, start_cropx + x + cw);
456 reg_w(sd, 0x13, start_cropy + y + ch);
457}
458
459static void w9968cf_mode_init_regs(struct sd *sd)
460{
461 int val, vs_polarity, hs_polarity;
462
463 w9968cf_set_crop_window(sd);
464
465 reg_w(sd, 0x14, sd->gspca_dev.pixfmt.width);
466 reg_w(sd, 0x15, sd->gspca_dev.pixfmt.height);
467
468
469 reg_w(sd, 0x30, sd->gspca_dev.pixfmt.width);
470 reg_w(sd, 0x31, sd->gspca_dev.pixfmt.height);
471
472
473 if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
474 V4L2_PIX_FMT_JPEG) {
475 reg_w(sd, 0x2c, sd->gspca_dev.pixfmt.width / 2);
476 reg_w(sd, 0x2d, sd->gspca_dev.pixfmt.width / 4);
477 } else
478 reg_w(sd, 0x2c, sd->gspca_dev.pixfmt.width);
479
480 reg_w(sd, 0x00, 0xbf17);
481 reg_w(sd, 0x00, 0xbf10);
482
483
484 val = sd->gspca_dev.pixfmt.width * sd->gspca_dev.pixfmt.height;
485 reg_w(sd, 0x3d, val & 0xffff);
486 reg_w(sd, 0x3e, val >> 16);
487
488 if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
489 V4L2_PIX_FMT_JPEG) {
490
491 jpeg_define(sd->jpeg_hdr, sd->gspca_dev.pixfmt.height,
492 sd->gspca_dev.pixfmt.width, 0x22);
493 jpeg_set_qual(sd->jpeg_hdr, v4l2_ctrl_g_ctrl(sd->jpegqual));
494 w9968cf_upload_quantizationtables(sd);
495 v4l2_ctrl_grab(sd->jpegqual, true);
496 }
497
498
499 if (sd->sensor == SEN_OV7620) {
500
501 vs_polarity = 1;
502 hs_polarity = 1;
503 } else {
504 vs_polarity = 1;
505 hs_polarity = 0;
506 }
507
508 val = (vs_polarity << 12) | (hs_polarity << 11);
509
510
511
512
513
514 if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
515 V4L2_PIX_FMT_JPEG) {
516
517 val |= 0x0003;
518 } else
519 val |= 0x0080;
520
521
522
523
524
525 val |= 0x8000;
526
527 reg_w(sd, 0x16, val);
528
529 sd->gspca_dev.empty_packet = 0;
530}
531
532static void w9968cf_stop0(struct sd *sd)
533{
534 v4l2_ctrl_grab(sd->jpegqual, false);
535 reg_w(sd, 0x39, 0x0000);
536 reg_w(sd, 0x16, 0x0000);
537}
538
539
540
541
542
543
544
545
546
547static void w9968cf_pkt_scan(struct gspca_dev *gspca_dev,
548 u8 *data,
549 int len)
550{
551 struct sd *sd = (struct sd *) gspca_dev;
552
553 if (w9968cf_vga_mode[gspca_dev->curr_mode].pixelformat ==
554 V4L2_PIX_FMT_JPEG) {
555 if (len >= 2 &&
556 data[0] == 0xff &&
557 data[1] == 0xd8) {
558 gspca_frame_add(gspca_dev, LAST_PACKET,
559 NULL, 0);
560 gspca_frame_add(gspca_dev, FIRST_PACKET,
561 sd->jpeg_hdr, JPEG_HDR_SZ);
562
563
564 len -= 2;
565 data += 2;
566 }
567 } else {
568
569 if (gspca_dev->empty_packet) {
570 gspca_frame_add(gspca_dev, LAST_PACKET,
571 NULL, 0);
572 gspca_frame_add(gspca_dev, FIRST_PACKET,
573 NULL, 0);
574 gspca_dev->empty_packet = 0;
575 }
576 }
577 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
578}
579