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#include <linux/module.h>
32#include <linux/types.h>
33#include <linux/ioctl.h>
34#include <asm/uaccess.h>
35#include <linux/i2c.h>
36#include <linux/i2c-id.h>
37#include <linux/videodev.h>
38#include <linux/video_decoder.h>
39#include <media/v4l2-common.h>
40#include <media/v4l2-i2c-drv-legacy.h>
41
42MODULE_DESCRIPTION("Philips SAA7114H video decoder driver");
43MODULE_AUTHOR("Maxim Yevtyushkin");
44MODULE_LICENSE("GPL");
45
46static int debug;
47module_param(debug, int, 0);
48MODULE_PARM_DESC(debug, "Debug level (0-1)");
49
50
51
52struct saa7114 {
53 unsigned char reg[0xf0 * 2];
54
55 int norm;
56 int input;
57 int enable;
58 int bright;
59 int contrast;
60 int hue;
61 int sat;
62 int playback;
63};
64
65#define I2C_DELAY 10
66
67
68
69
70
71#define SAA_7114_NTSC_HSYNC_START (-17)
72#define SAA_7114_NTSC_HSYNC_STOP (-32)
73
74
75#define SAA_7114_NTSC_HOFFSET (6)
76#define SAA_7114_NTSC_VOFFSET (10)
77#define SAA_7114_NTSC_WIDTH (720)
78#define SAA_7114_NTSC_HEIGHT (250)
79
80#define SAA_7114_SECAM_HSYNC_START (-17)
81#define SAA_7114_SECAM_HSYNC_STOP (-32)
82
83#define SAA_7114_SECAM_HOFFSET (2)
84#define SAA_7114_SECAM_VOFFSET (10)
85#define SAA_7114_SECAM_WIDTH (720)
86#define SAA_7114_SECAM_HEIGHT (300)
87
88#define SAA_7114_PAL_HSYNC_START (-17)
89#define SAA_7114_PAL_HSYNC_STOP (-32)
90
91#define SAA_7114_PAL_HOFFSET (2)
92#define SAA_7114_PAL_VOFFSET (10)
93#define SAA_7114_PAL_WIDTH (720)
94#define SAA_7114_PAL_HEIGHT (300)
95
96
97
98#define SAA_7114_VERTICAL_CHROMA_OFFSET 0
99#define SAA_7114_VERTICAL_LUMA_OFFSET 0
100
101#define REG_ADDR(x) (((x) << 1) + 1)
102#define LOBYTE(x) ((unsigned char)((x) & 0xff))
103#define HIBYTE(x) ((unsigned char)(((x) >> 8) & 0xff))
104#define LOWORD(x) ((unsigned short int)((x) & 0xffff))
105#define HIWORD(x) ((unsigned short int)(((x) >> 16) & 0xffff))
106
107
108
109
110static inline int saa7114_write(struct i2c_client *client, u8 reg, u8 value)
111{
112 return i2c_smbus_write_byte_data(client, reg, value);
113}
114
115static int saa7114_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
116{
117 int ret = -1;
118 u8 reg;
119
120
121
122 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
123
124 u8 block_data[32];
125 int block_len;
126
127 while (len >= 2) {
128 block_len = 0;
129 block_data[block_len++] = reg = data[0];
130 do {
131 block_data[block_len++] = data[1];
132 reg++;
133 len -= 2;
134 data += 2;
135 } while (len >= 2 && data[0] == reg && block_len < 32);
136 ret = i2c_master_send(client, block_data, block_len);
137 if (ret < 0)
138 break;
139 }
140 } else {
141
142 while (len >= 2) {
143 reg = *data++;
144 ret = saa7114_write(client, reg, *data++);
145 if (ret < 0)
146 break;
147 len -= 2;
148 }
149 }
150
151 return ret;
152}
153
154static inline int saa7114_read(struct i2c_client *client, u8 reg)
155{
156 return i2c_smbus_read_byte_data(client, reg);
157}
158
159
160
161
162
163
164static const unsigned char init[] = {
165 0x00, 0x00,
166
167 0x01, 0x08,
168
169
170 0x02, 0x00,
171
172 0x03, 0x10,
173
174 0x04, 0x90,
175 0x05, 0x90,
176 0x06, SAA_7114_NTSC_HSYNC_START,
177
178 0x07, SAA_7114_NTSC_HSYNC_STOP,
179
180 0x08, 0xb8,
181
182
183 0x09, 0x80,
184
185 0x0a, 0x80,
186 0x0b, 0x44,
187 0x0c, 0x40,
188 0x0d, 0x00,
189 0x0e, 0x84,
190
191 0x0f, 0x24,
192
193 0x10, 0x03,
194
195 0x11, 0x59,
196
197 0x12, 0xc9,
198
199 0x13, 0x80,
200 0x14, 0x00,
201 0x15, 0x00,
202 0x16, 0xfe,
203 0x17, 0x00,
204 0x18, 0x40,
205 0x19, 0x80,
206 0x1a, 0x00,
207 0x1b, 0x00,
208 0x1c, 0x00,
209 0x1d, 0x00,
210 0x1e, 0x00,
211 0x1f, 0x00,
212 0x20, 0x00,
213 0x21, 0x00,
214 0x22, 0x00,
215 0x23, 0x00,
216 0x24, 0x00,
217 0x25, 0x00,
218 0x26, 0x00,
219 0x27, 0x00,
220 0x28, 0x00,
221 0x29, 0x00,
222 0x2a, 0x00,
223 0x2b, 0x00,
224 0x2c, 0x00,
225 0x2d, 0x00,
226 0x2e, 0x00,
227 0x2f, 0x00,
228 0x30, 0xbc,
229 0x31, 0xdf,
230 0x32, 0x02,
231 0x33, 0x00,
232 0x34, 0xcd,
233 0x35, 0xcc,
234 0x36, 0x3a,
235 0x37, 0x00,
236 0x38, 0x03,
237 0x39, 0x10,
238 0x3a, 0x00,
239 0x3b, 0x00,
240 0x3c, 0x00,
241 0x3d, 0x00,
242 0x3e, 0x00,
243 0x3f, 0x00,
244 0x40, 0x00,
245 0x41, 0xff,
246 0x42, 0xff,
247 0x43, 0xff,
248 0x44, 0xff,
249 0x45, 0xff,
250 0x46, 0xff,
251 0x47, 0xff,
252 0x48, 0xff,
253 0x49, 0xff,
254 0x4a, 0xff,
255 0x4b, 0xff,
256 0x4c, 0xff,
257 0x4d, 0xff,
258 0x4e, 0xff,
259 0x4f, 0xff,
260 0x50, 0xff,
261 0x51, 0xff,
262 0x52, 0xff,
263 0x53, 0xff,
264 0x54, 0xff,
265 0x55, 0xff,
266 0x56, 0xff,
267 0x57, 0xff,
268 0x58, 0x40,
269 0x59, 0x47,
270 0x5a, 0x06,
271 0x5b, 0x83,
272 0x5c, 0x00,
273 0x5d, 0x3e,
274 0x5e, 0x00,
275 0x5f, 0x00,
276 0x60, 0x00,
277 0x61, 0x00,
278 0x62, 0x00,
279 0x63, 0x00,
280 0x64, 0x00,
281 0x65, 0x00,
282 0x66, 0x00,
283 0x67, 0x00,
284 0x68, 0x00,
285 0x69, 0x00,
286 0x6a, 0x00,
287 0x6b, 0x00,
288 0x6c, 0x00,
289 0x6d, 0x00,
290 0x6e, 0x00,
291 0x6f, 0x00,
292 0x70, 0x00,
293 0x71, 0x00,
294 0x72, 0x00,
295 0x73, 0x00,
296 0x74, 0x00,
297 0x75, 0x00,
298 0x76, 0x00,
299 0x77, 0x00,
300 0x78, 0x00,
301 0x79, 0x00,
302 0x7a, 0x00,
303 0x7b, 0x00,
304 0x7c, 0x00,
305 0x7d, 0x00,
306 0x7e, 0x00,
307 0x7f, 0x00,
308 0x80, 0x00,
309 0x81, 0x00,
310 0x82, 0x00,
311 0x83, 0x00,
312 0x84, 0xc5,
313 0x85, 0x0d,
314 0x86, 0x40,
315 0x87, 0x01,
316 0x88, 0x00,
317 0x89, 0x00,
318 0x8a, 0x00,
319 0x8b, 0x00,
320 0x8c, 0x00,
321 0x8d, 0x00,
322 0x8e, 0x00,
323 0x8f, 0x00,
324 0x90, 0x03,
325 0x91, 0x08,
326 0x92, 0x00,
327 0x93, 0x40,
328 0x94, 0x00,
329 0x95, 0x00,
330 0x96, 0x00,
331 0x97, 0x00,
332 0x98, 0x00,
333 0x99, 0x00,
334 0x9a, 0x00,
335 0x9b, 0x00,
336 0x9c, 0x00,
337 0x9d, 0x00,
338 0x9e, 0x00,
339 0x9f, 0x00,
340 0xa0, 0x01,
341 0xa1, 0x00,
342
343 0xa2, 0x00,
344
345 0xa3, 0x00,
346 0xa4, 0x80,
347 0xa5, 0x40,
348 0xa6, 0x40,
349 0xa7, 0x00,
350 0xa8, 0x00,
351 0xa9, 0x04,
352 0xaa, 0x00,
353 0xab, 0x00,
354 0xac, 0x00,
355 0xad, 0x02,
356 0xae, 0x00,
357 0xaf, 0x00,
358 0xb0, 0x00,
359 0xb1, 0x04,
360 0xb2, 0x00,
361 0xb3, 0x04,
362 0xb4, 0x00,
363 0xb5, 0x00,
364 0xb6, 0x00,
365 0xb7, 0x00,
366 0xb8, 0x00,
367 0xb9, 0x00,
368 0xba, 0x00,
369 0xbb, 0x00,
370 0xbc, 0x00,
371 0xbd, 0x00,
372 0xbe, 0x00,
373 0xbf, 0x00,
374 0xc0, 0x02,
375 0xc1, 0x08,
376 0xc2, 0x00,
377 0xc3, 0x40,
378 0xc4, 0x00,
379 0xc5, 0x00,
380 0xc6, 0x00,
381 0xc7, 0x00,
382 0xc8, 0x00,
383 0xc9, 0x00,
384 0xca, 0x00,
385 0xcb, 0x00,
386 0xcc, 0x00,
387 0xcd, 0x00,
388 0xce, 0x00,
389 0xcf, 0x00,
390 0xd0, 0x01,
391 0xd1, 0x00,
392 0xd2, 0x00,
393 0xd3, 0x00,
394 0xd4, 0x80,
395 0xd5, 0x40,
396 0xd6, 0x40,
397 0xd7, 0x00,
398 0xd8, 0x00,
399 0xd9, 0x04,
400 0xda, 0x00,
401 0xdb, 0x00,
402 0xdc, 0x00,
403 0xdd, 0x02,
404 0xde, 0x00,
405 0xdf, 0x00,
406 0xe0, 0x00,
407 0xe1, 0x04,
408 0xe2, 0x00,
409 0xe3, 0x04,
410 0xe4, 0x00,
411 0xe5, 0x00,
412 0xe6, 0x00,
413 0xe7, 0x00,
414 0xe8, 0x00,
415 0xe9, 0x00,
416 0xea, 0x00,
417 0xeb, 0x00,
418 0xec, 0x00,
419 0xed, 0x00,
420 0xee, 0x00,
421 0xef, 0x00
422};
423
424static int saa7114_command(struct i2c_client *client, unsigned cmd, void *arg)
425{
426 struct saa7114 *decoder = i2c_get_clientdata(client);
427
428 switch (cmd) {
429 case 0:
430
431
432 break;
433
434 case DECODER_DUMP:
435 {
436 int i;
437
438 if (!debug)
439 break;
440 v4l_info(client, "decoder dump\n");
441
442 for (i = 0; i < 32; i += 16) {
443 int j;
444
445 v4l_info(client, "%03x", i);
446 for (j = 0; j < 16; ++j) {
447 printk(KERN_CONT " %02x",
448 saa7114_read(client, i + j));
449 }
450 printk(KERN_CONT "\n");
451 }
452 break;
453 }
454
455 case DECODER_GET_CAPABILITIES:
456 {
457 struct video_decoder_capability *cap = arg;
458
459 v4l_dbg(1, debug, client, "get capabilities\n");
460
461 cap->flags = VIDEO_DECODER_PAL |
462 VIDEO_DECODER_NTSC |
463 VIDEO_DECODER_AUTO |
464 VIDEO_DECODER_CCIR;
465 cap->inputs = 8;
466 cap->outputs = 1;
467 break;
468 }
469
470 case DECODER_GET_STATUS:
471 {
472 int *iarg = arg;
473 int status;
474 int res;
475
476 status = saa7114_read(client, 0x1f);
477
478 v4l_dbg(1, debug, client, "status: 0x%02x\n", status);
479 res = 0;
480 if ((status & (1 << 6)) == 0) {
481 res |= DECODER_STATUS_GOOD;
482 }
483 switch (decoder->norm) {
484 case VIDEO_MODE_NTSC:
485 res |= DECODER_STATUS_NTSC;
486 break;
487 case VIDEO_MODE_PAL:
488 res |= DECODER_STATUS_PAL;
489 break;
490 case VIDEO_MODE_SECAM:
491 res |= DECODER_STATUS_SECAM;
492 break;
493 default:
494 case VIDEO_MODE_AUTO:
495 if ((status & (1 << 5)) != 0) {
496 res |= DECODER_STATUS_NTSC;
497 } else {
498 res |= DECODER_STATUS_PAL;
499 }
500 break;
501 }
502 if ((status & (1 << 0)) != 0) {
503 res |= DECODER_STATUS_COLOR;
504 }
505 *iarg = res;
506 break;
507 }
508
509 case DECODER_SET_NORM:
510 {
511 int *iarg = arg;
512
513 short int hoff = 0, voff = 0, w = 0, h = 0;
514
515 v4l_dbg(1, debug, client, "set norm\n");
516
517 switch (*iarg) {
518 case VIDEO_MODE_NTSC:
519 v4l_dbg(1, debug, client, "NTSC\n");
520 decoder->reg[REG_ADDR(0x06)] =
521 SAA_7114_NTSC_HSYNC_START;
522 decoder->reg[REG_ADDR(0x07)] =
523 SAA_7114_NTSC_HSYNC_STOP;
524
525 decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8;
526
527 decoder->reg[REG_ADDR(0x0e)] = 0x85;
528 decoder->reg[REG_ADDR(0x0f)] = 0x24;
529
530 hoff = SAA_7114_NTSC_HOFFSET;
531 voff = SAA_7114_NTSC_VOFFSET;
532 w = SAA_7114_NTSC_WIDTH;
533 h = SAA_7114_NTSC_HEIGHT;
534
535 break;
536
537 case VIDEO_MODE_PAL:
538 v4l_dbg(1, debug, client, "PAL\n");
539 decoder->reg[REG_ADDR(0x06)] =
540 SAA_7114_PAL_HSYNC_START;
541 decoder->reg[REG_ADDR(0x07)] =
542 SAA_7114_PAL_HSYNC_STOP;
543
544 decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8;
545
546 decoder->reg[REG_ADDR(0x0e)] = 0x81;
547 decoder->reg[REG_ADDR(0x0f)] = 0x24;
548
549 hoff = SAA_7114_PAL_HOFFSET;
550 voff = SAA_7114_PAL_VOFFSET;
551 w = SAA_7114_PAL_WIDTH;
552 h = SAA_7114_PAL_HEIGHT;
553
554 break;
555
556 default:
557 v4l_dbg(1, debug, client, "Unknown video mode\n");
558 return -EINVAL;
559 }
560
561
562 decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff);
563 decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f;
564 decoder->reg[REG_ADDR(0x96)] = LOBYTE(w);
565 decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f;
566 decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff);
567 decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f;
568 decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2);
569 decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f;
570 decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w);
571 decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f;
572 decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h);
573 decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f;
574
575 decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff);
576 decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f;
577 decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w);
578 decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f;
579 decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff);
580 decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f;
581 decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2);
582 decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f;
583 decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w);
584 decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f;
585 decoder->reg[REG_ADDR(0xce)] = LOBYTE(h);
586 decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f;
587
588
589 saa7114_write(client, 0x80, 0x06);
590 saa7114_write(client, 0x88, 0xd8);
591 saa7114_write(client, 0x88, 0xf8);
592
593 saa7114_write_block(client, decoder->reg + (0x06 << 1),
594 3 << 1);
595 saa7114_write_block(client, decoder->reg + (0x0e << 1),
596 2 << 1);
597 saa7114_write_block(client, decoder->reg + (0x5a << 1),
598 2 << 1);
599
600 saa7114_write_block(client, decoder->reg + (0x94 << 1),
601 (0x9f + 1 - 0x94) << 1);
602 saa7114_write_block(client, decoder->reg + (0xc4 << 1),
603 (0xcf + 1 - 0xc4) << 1);
604
605 saa7114_write(client, 0x88, 0xd8);
606 saa7114_write(client, 0x88, 0xf8);
607 saa7114_write(client, 0x80, 0x36);
608
609 decoder->norm = *iarg;
610 break;
611 }
612
613 case DECODER_SET_INPUT:
614 {
615 int *iarg = arg;
616
617 v4l_dbg(1, debug, client, "set input (%d)\n", *iarg);
618 if (*iarg < 0 || *iarg > 7) {
619 return -EINVAL;
620 }
621
622 if (decoder->input != *iarg) {
623 v4l_dbg(1, debug, client, "now setting %s input\n",
624 *iarg >= 6 ? "S-Video" : "Composite");
625 decoder->input = *iarg;
626
627
628 decoder->reg[REG_ADDR(0x02)] =
629 (decoder->
630 reg[REG_ADDR(0x02)] & 0xf0) | (decoder->
631 input <
632 6 ? 0x0 : 0x9);
633 saa7114_write(client, 0x02,
634 decoder->reg[REG_ADDR(0x02)]);
635
636
637 decoder->reg[REG_ADDR(0x09)] =
638 (decoder->
639 reg[REG_ADDR(0x09)] & 0x7f) | (decoder->
640 input <
641 6 ? 0x0 :
642 0x80);
643 saa7114_write(client, 0x09,
644 decoder->reg[REG_ADDR(0x09)]);
645
646 decoder->reg[REG_ADDR(0x0e)] =
647 decoder->input <
648 6 ? decoder->
649 reg[REG_ADDR(0x0e)] | 1 : decoder->
650 reg[REG_ADDR(0x0e)] & ~1;
651 saa7114_write(client, 0x0e,
652 decoder->reg[REG_ADDR(0x0e)]);
653 }
654 break;
655 }
656
657 case DECODER_SET_OUTPUT:
658 {
659 int *iarg = arg;
660
661 v4l_dbg(1, debug, client, "set output\n");
662
663
664 if (*iarg != 0) {
665 return -EINVAL;
666 }
667 break;
668 }
669
670 case DECODER_ENABLE_OUTPUT:
671 {
672 int *iarg = arg;
673 int enable = (*iarg != 0);
674
675 v4l_dbg(1, debug, client, "%s output\n",
676 enable ? "enable" : "disable");
677
678 decoder->playback = !enable;
679
680 if (decoder->enable != enable) {
681 decoder->enable = enable;
682
683
684
685
686
687
688
689
690
691
692
693 if (decoder->enable) {
694 decoder->reg[REG_ADDR(0x08)] = 0xb8;
695 decoder->reg[REG_ADDR(0x12)] = 0xc9;
696 decoder->reg[REG_ADDR(0x13)] = 0x80;
697 decoder->reg[REG_ADDR(0x87)] = 0x01;
698 } else {
699 decoder->reg[REG_ADDR(0x08)] = 0x7c;
700 decoder->reg[REG_ADDR(0x12)] = 0x00;
701 decoder->reg[REG_ADDR(0x13)] = 0x00;
702 decoder->reg[REG_ADDR(0x87)] = 0x00;
703 }
704
705 saa7114_write_block(client,
706 decoder->reg + (0x12 << 1),
707 2 << 1);
708 saa7114_write(client, 0x08,
709 decoder->reg[REG_ADDR(0x08)]);
710 saa7114_write(client, 0x87,
711 decoder->reg[REG_ADDR(0x87)]);
712 saa7114_write(client, 0x88, 0xd8);
713 saa7114_write(client, 0x88, 0xf8);
714 saa7114_write(client, 0x80, 0x36);
715
716 }
717 break;
718 }
719
720 case DECODER_SET_PICTURE:
721 {
722 struct video_picture *pic = arg;
723
724 v4l_dbg(1, debug, client,
725 "decoder set picture bright=%d contrast=%d saturation=%d hue=%d\n",
726 pic->brightness, pic->contrast, pic->colour, pic->hue);
727
728 if (decoder->bright != pic->brightness) {
729
730 decoder->bright = pic->brightness;
731 saa7114_write(client, 0x0a, decoder->bright >> 8);
732 }
733 if (decoder->contrast != pic->contrast) {
734
735 decoder->contrast = pic->contrast;
736 saa7114_write(client, 0x0b,
737 decoder->contrast >> 9);
738 }
739 if (decoder->sat != pic->colour) {
740
741 decoder->sat = pic->colour;
742 saa7114_write(client, 0x0c, decoder->sat >> 9);
743 }
744 if (decoder->hue != pic->hue) {
745
746 decoder->hue = pic->hue;
747 saa7114_write(client, 0x0d,
748 (decoder->hue - 32768) >> 8);
749 }
750 break;
751 }
752
753 default:
754 return -EINVAL;
755 }
756
757 return 0;
758}
759
760
761
762static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END };
763
764I2C_CLIENT_INSMOD;
765
766static int saa7114_probe(struct i2c_client *client,
767 const struct i2c_device_id *id)
768{
769 int i, err[30];
770 short int hoff = SAA_7114_NTSC_HOFFSET;
771 short int voff = SAA_7114_NTSC_VOFFSET;
772 short int w = SAA_7114_NTSC_WIDTH;
773 short int h = SAA_7114_NTSC_HEIGHT;
774 struct saa7114 *decoder;
775
776
777 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
778 return -ENODEV;
779
780 v4l_info(client, "chip found @ 0x%x (%s)\n",
781 client->addr << 1, client->adapter->name);
782
783 decoder = kzalloc(sizeof(struct saa7114), GFP_KERNEL);
784 if (decoder == NULL)
785 return -ENOMEM;
786 decoder->norm = VIDEO_MODE_NTSC;
787 decoder->input = -1;
788 decoder->enable = 1;
789 decoder->bright = 32768;
790 decoder->contrast = 32768;
791 decoder->hue = 32768;
792 decoder->sat = 32768;
793 decoder->playback = 0;
794 i2c_set_clientdata(client, decoder);
795
796 memcpy(decoder->reg, init, sizeof(init));
797
798 decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff);
799 decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f;
800 decoder->reg[REG_ADDR(0x96)] = LOBYTE(w);
801 decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f;
802 decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff);
803 decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f;
804 decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2);
805 decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f;
806 decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w);
807 decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f;
808 decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h);
809 decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f;
810
811 decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff);
812 decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f;
813 decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w);
814 decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f;
815 decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff);
816 decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f;
817 decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2);
818 decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f;
819 decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w);
820 decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f;
821 decoder->reg[REG_ADDR(0xce)] = LOBYTE(h);
822 decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f;
823
824 decoder->reg[REG_ADDR(0xb8)] =
825 LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
826 decoder->reg[REG_ADDR(0xb9)] =
827 HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
828 decoder->reg[REG_ADDR(0xba)] =
829 LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
830 decoder->reg[REG_ADDR(0xbb)] =
831 HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
832
833 decoder->reg[REG_ADDR(0xbc)] =
834 LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
835 decoder->reg[REG_ADDR(0xbd)] =
836 HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
837 decoder->reg[REG_ADDR(0xbe)] =
838 LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
839 decoder->reg[REG_ADDR(0xbf)] =
840 HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
841
842 decoder->reg[REG_ADDR(0xe8)] =
843 LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
844 decoder->reg[REG_ADDR(0xe9)] =
845 HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
846 decoder->reg[REG_ADDR(0xea)] =
847 LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
848 decoder->reg[REG_ADDR(0xeb)] =
849 HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
850
851 decoder->reg[REG_ADDR(0xec)] =
852 LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
853 decoder->reg[REG_ADDR(0xed)] =
854 HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
855 decoder->reg[REG_ADDR(0xee)] =
856 LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
857 decoder->reg[REG_ADDR(0xef)] =
858 HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
859
860
861 decoder->reg[REG_ADDR(0x13)] = 0x80;
862 decoder->reg[REG_ADDR(0x87)] = 0x01;
863 decoder->reg[REG_ADDR(0x12)] = 0xc9;
864
865 decoder->reg[REG_ADDR(0x02)] = 0xc0;
866 decoder->reg[REG_ADDR(0x09)] = 0x00;
867 decoder->reg[REG_ADDR(0x0e)] |= 1;
868
869
870 v4l_dbg(1, debug, client, "starting init\n");
871
872 err[0] =
873 saa7114_write_block(client, decoder->reg + (0x20 << 1),
874 0x10 << 1);
875 err[1] =
876 saa7114_write_block(client, decoder->reg + (0x30 << 1),
877 0x10 << 1);
878 err[2] =
879 saa7114_write_block(client, decoder->reg + (0x63 << 1),
880 (0x7f + 1 - 0x63) << 1);
881 err[3] =
882 saa7114_write_block(client, decoder->reg + (0x89 << 1),
883 6 << 1);
884 err[4] =
885 saa7114_write_block(client, decoder->reg + (0xb8 << 1),
886 8 << 1);
887 err[5] =
888 saa7114_write_block(client, decoder->reg + (0xe8 << 1),
889 8 << 1);
890
891
892 for (i = 0; i <= 5; i++) {
893 if (err[i] < 0) {
894 v4l_dbg(1, debug, client,
895 "init error %d at stage %d, leaving attach.\n",
896 i, err[i]);
897 kfree(decoder);
898 return -EIO;
899 }
900 }
901
902 for (i = 6; i < 8; i++) {
903 v4l_dbg(1, debug, client,
904 "reg[0x%02x] = 0x%02x (0x%02x)\n",
905 i, saa7114_read(client, i),
906 decoder->reg[REG_ADDR(i)]);
907 }
908
909 v4l_dbg(1, debug, client,
910 "performing decoder reset sequence\n");
911
912 err[6] = saa7114_write(client, 0x80, 0x06);
913 err[7] = saa7114_write(client, 0x88, 0xd8);
914 err[8] = saa7114_write(client, 0x88, 0xf8);
915
916 for (i = 6; i <= 8; i++) {
917 if (err[i] < 0) {
918 v4l_dbg(1, debug, client,
919 "init error %d at stage %d, leaving attach.\n",
920 i, err[i]);
921 kfree(decoder);
922 return -EIO;
923 }
924 }
925
926 v4l_dbg(1, debug, client, "performing the rest of init\n");
927
928 err[9] = saa7114_write(client, 0x01, decoder->reg[REG_ADDR(0x01)]);
929 err[10] = saa7114_write_block(client, decoder->reg + (0x03 << 1), (0x1e + 1 - 0x03) << 1);
930 err[11] = saa7114_write_block(client, decoder->reg + (0x40 << 1), (0x5f + 1 - 0x40) << 1);
931 err[12] = saa7114_write_block(client, decoder->reg + (0x81 << 1), 2 << 1);
932 err[13] = saa7114_write_block(client, decoder->reg + (0x83 << 1), 5 << 1);
933 err[14] = saa7114_write_block(client, decoder->reg + (0x90 << 1), 4 << 1);
934 err[15] =
935 saa7114_write_block(client, decoder->reg + (0x94 << 1),
936 12 << 1);
937 err[16] =
938 saa7114_write_block(client, decoder->reg + (0xa0 << 1),
939 8 << 1);
940 err[17] =
941 saa7114_write_block(client, decoder->reg + (0xa8 << 1),
942 8 << 1);
943 err[18] =
944 saa7114_write_block(client, decoder->reg + (0xb0 << 1),
945 8 << 1);
946 err[19] = saa7114_write_block(client, decoder->reg + (0xc0 << 1), 4 << 1);
947 err[15] =
948 saa7114_write_block(client, decoder->reg + (0xc4 << 1),
949 12 << 1);
950 err[16] =
951 saa7114_write_block(client, decoder->reg + (0xd0 << 1),
952 8 << 1);
953 err[17] =
954 saa7114_write_block(client, decoder->reg + (0xd8 << 1),
955 8 << 1);
956 err[18] =
957 saa7114_write_block(client, decoder->reg + (0xe0 << 1),
958 8 << 1);
959
960 for (i = 9; i <= 18; i++) {
961 if (err[i] < 0) {
962 v4l_dbg(1, debug, client,
963 "init error %d at stage %d, leaving attach.\n",
964 i, err[i]);
965 kfree(decoder);
966 return -EIO;
967 }
968 }
969
970
971 for (i = 6; i < 8; i++) {
972 v4l_dbg(1, debug, client,
973 "reg[0x%02x] = 0x%02x (0x%02x)\n",
974 i, saa7114_read(client, i),
975 decoder->reg[REG_ADDR(i)]);
976 }
977
978
979 for (i = 0x11; i <= 0x13; i++) {
980 v4l_dbg(1, debug, client,
981 "reg[0x%02x] = 0x%02x (0x%02x)\n",
982 i, saa7114_read(client, i),
983 decoder->reg[REG_ADDR(i)]);
984 }
985
986
987 v4l_dbg(1, debug, client, "setting video input\n");
988
989 err[19] =
990 saa7114_write(client, 0x02, decoder->reg[REG_ADDR(0x02)]);
991 err[20] =
992 saa7114_write(client, 0x09, decoder->reg[REG_ADDR(0x09)]);
993 err[21] =
994 saa7114_write(client, 0x0e, decoder->reg[REG_ADDR(0x0e)]);
995
996 for (i = 19; i <= 21; i++) {
997 if (err[i] < 0) {
998 v4l_dbg(1, debug, client,
999 "init error %d at stage %d, leaving attach.\n",
1000 i, err[i]);
1001 kfree(decoder);
1002 return -EIO;
1003 }
1004 }
1005
1006 v4l_dbg(1, debug, client, "performing decoder reset sequence\n");
1007
1008 err[22] = saa7114_write(client, 0x88, 0xd8);
1009 err[23] = saa7114_write(client, 0x88, 0xf8);
1010 err[24] = saa7114_write(client, 0x80, 0x36);
1011
1012
1013 for (i = 22; i <= 24; i++) {
1014 if (err[i] < 0) {
1015 v4l_dbg(1, debug, client,
1016 "init error %d at stage %d, leaving attach.\n",
1017 i, err[i]);
1018 kfree(decoder);
1019 return -EIO;
1020 }
1021 }
1022
1023 err[25] = saa7114_write(client, 0x06, init[REG_ADDR(0x06)]);
1024 err[26] = saa7114_write(client, 0x07, init[REG_ADDR(0x07)]);
1025 err[27] = saa7114_write(client, 0x10, init[REG_ADDR(0x10)]);
1026
1027 v4l_dbg(1, debug, client, "chip version %x, decoder status 0x%02x\n",
1028 saa7114_read(client, 0x00) >> 4,
1029 saa7114_read(client, 0x1f));
1030 v4l_dbg(1, debug, client,
1031 "power save control: 0x%02x, scaler status: 0x%02x\n",
1032 saa7114_read(client, 0x88),
1033 saa7114_read(client, 0x8f));
1034
1035
1036 for (i = 0x94; i < 0x96; i++) {
1037 v4l_dbg(1, debug, client,
1038 "reg[0x%02x] = 0x%02x (0x%02x)\n",
1039 i, saa7114_read(client, i),
1040 decoder->reg[REG_ADDR(i)]);
1041 }
1042
1043
1044 return 0;
1045}
1046
1047static int saa7114_remove(struct i2c_client *client)
1048{
1049 kfree(i2c_get_clientdata(client));
1050 return 0;
1051}
1052
1053
1054
1055static const struct i2c_device_id saa7114_id[] = {
1056 { "saa7114_old", 0 },
1057 { }
1058};
1059MODULE_DEVICE_TABLE(i2c, saa7114_id);
1060
1061static struct v4l2_i2c_driver_data v4l2_i2c_data = {
1062 .name = "saa7114",
1063 .driverid = I2C_DRIVERID_SAA7114,
1064 .command = saa7114_command,
1065 .probe = saa7114_probe,
1066 .remove = saa7114_remove,
1067 .id_table = saa7114_id,
1068};
1069