Linux 2.6.17.7
[linux/fpc-iii.git] / drivers / media / video / saa7114.c
blob90398ab8252e62053a6fcf54e41af77a31500d9a
1 /*
2 * saa7114 - Philips SAA7114H video decoder driver version 0.0.1
4 * Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com>
6 * Based on saa7111 driver by Dave Perks
8 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
10 * Slight changes for video timing and attachment output by
11 * Wolfgang Scherr <scherr@net4you.net>
13 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
14 * - moved over to linux>=2.4.x i2c protocol (1/1/2003)
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 #include <linux/module.h>
32 #include <linux/init.h>
33 #include <linux/delay.h>
34 #include <linux/errno.h>
35 #include <linux/fs.h>
36 #include <linux/kernel.h>
37 #include <linux/major.h>
39 #include <linux/slab.h>
41 #include <linux/mm.h>
42 #include <linux/pci.h>
43 #include <linux/signal.h>
44 #include <asm/io.h>
45 #include <asm/pgtable.h>
46 #include <asm/page.h>
47 #include <linux/sched.h>
48 #include <linux/types.h>
50 #include <linux/videodev.h>
51 #include <asm/uaccess.h>
53 MODULE_DESCRIPTION("Philips SAA7114H video decoder driver");
54 MODULE_AUTHOR("Maxim Yevtyushkin");
55 MODULE_LICENSE("GPL");
57 #include <linux/i2c.h>
59 #define I2C_NAME(x) (x)->name
61 #include <linux/video_decoder.h>
63 static int debug = 0;
64 module_param(debug, int, 0);
65 MODULE_PARM_DESC(debug, "Debug level (0-1)");
67 #define dprintk(num, format, args...) \
68 do { \
69 if (debug >= num) \
70 printk(format, ##args); \
71 } while (0)
73 /* ----------------------------------------------------------------------- */
75 struct saa7114 {
76 unsigned char reg[0xf0 * 2];
78 int norm;
79 int input;
80 int enable;
81 int bright;
82 int contrast;
83 int hue;
84 int sat;
85 int playback;
88 #define I2C_SAA7114 0x42
89 #define I2C_SAA7114A 0x40
91 #define I2C_DELAY 10
94 //#define SAA_7114_NTSC_HSYNC_START (-3)
95 //#define SAA_7114_NTSC_HSYNC_STOP (-18)
97 #define SAA_7114_NTSC_HSYNC_START (-17)
98 #define SAA_7114_NTSC_HSYNC_STOP (-32)
100 //#define SAA_7114_NTSC_HOFFSET (5)
101 #define SAA_7114_NTSC_HOFFSET (6)
102 #define SAA_7114_NTSC_VOFFSET (10)
103 #define SAA_7114_NTSC_WIDTH (720)
104 #define SAA_7114_NTSC_HEIGHT (250)
106 #define SAA_7114_SECAM_HSYNC_START (-17)
107 #define SAA_7114_SECAM_HSYNC_STOP (-32)
109 #define SAA_7114_SECAM_HOFFSET (2)
110 #define SAA_7114_SECAM_VOFFSET (10)
111 #define SAA_7114_SECAM_WIDTH (720)
112 #define SAA_7114_SECAM_HEIGHT (300)
114 #define SAA_7114_PAL_HSYNC_START (-17)
115 #define SAA_7114_PAL_HSYNC_STOP (-32)
117 #define SAA_7114_PAL_HOFFSET (2)
118 #define SAA_7114_PAL_VOFFSET (10)
119 #define SAA_7114_PAL_WIDTH (720)
120 #define SAA_7114_PAL_HEIGHT (300)
124 #define SAA_7114_VERTICAL_CHROMA_OFFSET 0 //0x50504040
125 #define SAA_7114_VERTICAL_LUMA_OFFSET 0
127 #define REG_ADDR(x) (((x) << 1) + 1)
128 #define LOBYTE(x) ((unsigned char)((x) & 0xff))
129 #define HIBYTE(x) ((unsigned char)(((x) >> 8) & 0xff))
130 #define LOWORD(x) ((unsigned short int)((x) & 0xffff))
131 #define HIWORD(x) ((unsigned short int)(((x) >> 16) & 0xffff))
134 /* ----------------------------------------------------------------------- */
136 static inline int
137 saa7114_write (struct i2c_client *client,
138 u8 reg,
139 u8 value)
141 return i2c_smbus_write_byte_data(client, reg, value);
144 static int
145 saa7114_write_block (struct i2c_client *client,
146 const u8 *data,
147 unsigned int len)
149 int ret = -1;
150 u8 reg;
152 /* the saa7114 has an autoincrement function, use it if
153 * the adapter understands raw I2C */
154 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
155 /* do raw I2C, not smbus compatible */
156 u8 block_data[32];
157 int block_len;
159 while (len >= 2) {
160 block_len = 0;
161 block_data[block_len++] = reg = data[0];
162 do {
163 block_data[block_len++] = data[1];
164 reg++;
165 len -= 2;
166 data += 2;
167 } while (len >= 2 && data[0] == reg &&
168 block_len < 32);
169 if ((ret = i2c_master_send(client, block_data,
170 block_len)) < 0)
171 break;
173 } else {
174 /* do some slow I2C emulation kind of thing */
175 while (len >= 2) {
176 reg = *data++;
177 if ((ret = saa7114_write(client, reg,
178 *data++)) < 0)
179 break;
180 len -= 2;
184 return ret;
187 static inline int
188 saa7114_read (struct i2c_client *client,
189 u8 reg)
191 return i2c_smbus_read_byte_data(client, reg);
194 /* ----------------------------------------------------------------------- */
196 // initially set NTSC, composite
199 static const unsigned char init[] = {
200 0x00, 0x00, /* 00 - ID byte , chip version,
201 * read only */
202 0x01, 0x08, /* 01 - X,X,X,X, IDEL3 to IDEL0 -
203 * horizontal increment delay,
204 * recommended position */
205 0x02, 0x00, /* 02 - FUSE=3, GUDL=2, MODE=0 ;
206 * input control */
207 0x03, 0x10, /* 03 - HLNRS=0, VBSL=1, WPOFF=0,
208 * HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
209 0x04, 0x90, /* 04 - GAI1=256 */
210 0x05, 0x90, /* 05 - GAI2=256 */
211 0x06, SAA_7114_NTSC_HSYNC_START, /* 06 - HSB: hsync start,
212 * depends on the video standard */
213 0x07, SAA_7114_NTSC_HSYNC_STOP, /* 07 - HSS: hsync stop, depends
214 *on the video standard */
215 0x08, 0xb8, /* 08 - AUFD=1, FSEL=1, EXFIL=0, VTRC=1,
216 * HPLL: free running in playback, locked
217 * in capture, VNOI=0 */
218 0x09, 0x80, /* 09 - BYPS=0, PREF=0, BPSS=0, VBLB=0,
219 * UPTCV=0, APER=1; depends from input */
220 0x0a, 0x80, /* 0a - BRIG=128 */
221 0x0b, 0x44, /* 0b - CONT=1.109 */
222 0x0c, 0x40, /* 0c - SATN=1.0 */
223 0x0d, 0x00, /* 0d - HUE=0 */
224 0x0e, 0x84, /* 0e - CDTO, CSTD2 to 0, DCVF, FCTC,
225 * CCOMB; depends from video standard */
226 0x0f, 0x24, /* 0f - ACGC,CGAIN6 to CGAIN0; depends
227 * from video standard */
228 0x10, 0x03, /* 10 - OFFU1 to 0, OFFV1 to 0, CHBW,
229 * LCBW2 to 0 */
230 0x11, 0x59, /* 11 - COLO, RTP1, HEDL1 to 0, RTP0,
231 * YDEL2 to 0 */
232 0x12, 0xc9, /* 12 - RT signal control RTSE13 to 10
233 * and 03 to 00 */
234 0x13, 0x80, /* 13 - RT/X port output control */
235 0x14, 0x00, /* 14 - analog, ADC, compatibility control */
236 0x15, 0x00, /* 15 - VGATE start FID change */
237 0x16, 0xfe, /* 16 - VGATE stop */
238 0x17, 0x00, /* 17 - Misc., VGATE MSBs */
239 0x18, 0x40, /* RAWG */
240 0x19, 0x80, /* RAWO */
241 0x1a, 0x00,
242 0x1b, 0x00,
243 0x1c, 0x00,
244 0x1d, 0x00,
245 0x1e, 0x00,
246 0x1f, 0x00, /* status byte, read only */
247 0x20, 0x00, /* video decoder reserved part */
248 0x21, 0x00,
249 0x22, 0x00,
250 0x23, 0x00,
251 0x24, 0x00,
252 0x25, 0x00,
253 0x26, 0x00,
254 0x27, 0x00,
255 0x28, 0x00,
256 0x29, 0x00,
257 0x2a, 0x00,
258 0x2b, 0x00,
259 0x2c, 0x00,
260 0x2d, 0x00,
261 0x2e, 0x00,
262 0x2f, 0x00,
263 0x30, 0xbc, /* audio clock generator */
264 0x31, 0xdf,
265 0x32, 0x02,
266 0x33, 0x00,
267 0x34, 0xcd,
268 0x35, 0xcc,
269 0x36, 0x3a,
270 0x37, 0x00,
271 0x38, 0x03,
272 0x39, 0x10,
273 0x3a, 0x00,
274 0x3b, 0x00,
275 0x3c, 0x00,
276 0x3d, 0x00,
277 0x3e, 0x00,
278 0x3f, 0x00,
279 0x40, 0x00, /* VBI data slicer */
280 0x41, 0xff,
281 0x42, 0xff,
282 0x43, 0xff,
283 0x44, 0xff,
284 0x45, 0xff,
285 0x46, 0xff,
286 0x47, 0xff,
287 0x48, 0xff,
288 0x49, 0xff,
289 0x4a, 0xff,
290 0x4b, 0xff,
291 0x4c, 0xff,
292 0x4d, 0xff,
293 0x4e, 0xff,
294 0x4f, 0xff,
295 0x50, 0xff,
296 0x51, 0xff,
297 0x52, 0xff,
298 0x53, 0xff,
299 0x54, 0xff,
300 0x55, 0xff,
301 0x56, 0xff,
302 0x57, 0xff,
303 0x58, 0x40, // framing code
304 0x59, 0x47, // horizontal offset
305 0x5a, 0x06, // vertical offset
306 0x5b, 0x83, // field offset
307 0x5c, 0x00, // reserved
308 0x5d, 0x3e, // header and data
309 0x5e, 0x00, // sliced data
310 0x5f, 0x00, // reserved
311 0x60, 0x00, /* video decoder reserved part */
312 0x61, 0x00,
313 0x62, 0x00,
314 0x63, 0x00,
315 0x64, 0x00,
316 0x65, 0x00,
317 0x66, 0x00,
318 0x67, 0x00,
319 0x68, 0x00,
320 0x69, 0x00,
321 0x6a, 0x00,
322 0x6b, 0x00,
323 0x6c, 0x00,
324 0x6d, 0x00,
325 0x6e, 0x00,
326 0x6f, 0x00,
327 0x70, 0x00, /* video decoder reserved part */
328 0x71, 0x00,
329 0x72, 0x00,
330 0x73, 0x00,
331 0x74, 0x00,
332 0x75, 0x00,
333 0x76, 0x00,
334 0x77, 0x00,
335 0x78, 0x00,
336 0x79, 0x00,
337 0x7a, 0x00,
338 0x7b, 0x00,
339 0x7c, 0x00,
340 0x7d, 0x00,
341 0x7e, 0x00,
342 0x7f, 0x00,
343 0x80, 0x00, /* X-port, I-port and scaler */
344 0x81, 0x00,
345 0x82, 0x00,
346 0x83, 0x00,
347 0x84, 0xc5,
348 0x85, 0x0d, // hsync and vsync ?
349 0x86, 0x40,
350 0x87, 0x01,
351 0x88, 0x00,
352 0x89, 0x00,
353 0x8a, 0x00,
354 0x8b, 0x00,
355 0x8c, 0x00,
356 0x8d, 0x00,
357 0x8e, 0x00,
358 0x8f, 0x00,
359 0x90, 0x03, /* Task A definition */
360 0x91, 0x08,
361 0x92, 0x00,
362 0x93, 0x40,
363 0x94, 0x00, // window settings
364 0x95, 0x00,
365 0x96, 0x00,
366 0x97, 0x00,
367 0x98, 0x00,
368 0x99, 0x00,
369 0x9a, 0x00,
370 0x9b, 0x00,
371 0x9c, 0x00,
372 0x9d, 0x00,
373 0x9e, 0x00,
374 0x9f, 0x00,
375 0xa0, 0x01, /* horizontal integer prescaling ratio */
376 0xa1, 0x00, /* horizontal prescaler accumulation
377 * sequence length */
378 0xa2, 0x00, /* UV FIR filter, Y FIR filter, prescaler
379 * DC gain */
380 0xa3, 0x00,
381 0xa4, 0x80, // luminance brightness
382 0xa5, 0x40, // luminance gain
383 0xa6, 0x40, // chrominance saturation
384 0xa7, 0x00,
385 0xa8, 0x00, // horizontal luminance scaling increment
386 0xa9, 0x04,
387 0xaa, 0x00, // horizontal luminance phase offset
388 0xab, 0x00,
389 0xac, 0x00, // horizontal chrominance scaling increment
390 0xad, 0x02,
391 0xae, 0x00, // horizontal chrominance phase offset
392 0xaf, 0x00,
393 0xb0, 0x00, // vertical luminance scaling increment
394 0xb1, 0x04,
395 0xb2, 0x00, // vertical chrominance scaling increment
396 0xb3, 0x04,
397 0xb4, 0x00,
398 0xb5, 0x00,
399 0xb6, 0x00,
400 0xb7, 0x00,
401 0xb8, 0x00,
402 0xb9, 0x00,
403 0xba, 0x00,
404 0xbb, 0x00,
405 0xbc, 0x00,
406 0xbd, 0x00,
407 0xbe, 0x00,
408 0xbf, 0x00,
409 0xc0, 0x02, // Task B definition
410 0xc1, 0x08,
411 0xc2, 0x00,
412 0xc3, 0x40,
413 0xc4, 0x00, // window settings
414 0xc5, 0x00,
415 0xc6, 0x00,
416 0xc7, 0x00,
417 0xc8, 0x00,
418 0xc9, 0x00,
419 0xca, 0x00,
420 0xcb, 0x00,
421 0xcc, 0x00,
422 0xcd, 0x00,
423 0xce, 0x00,
424 0xcf, 0x00,
425 0xd0, 0x01, // horizontal integer prescaling ratio
426 0xd1, 0x00, // horizontal prescaler accumulation sequence length
427 0xd2, 0x00, // UV FIR filter, Y FIR filter, prescaler DC gain
428 0xd3, 0x00,
429 0xd4, 0x80, // luminance brightness
430 0xd5, 0x40, // luminance gain
431 0xd6, 0x40, // chrominance saturation
432 0xd7, 0x00,
433 0xd8, 0x00, // horizontal luminance scaling increment
434 0xd9, 0x04,
435 0xda, 0x00, // horizontal luminance phase offset
436 0xdb, 0x00,
437 0xdc, 0x00, // horizontal chrominance scaling increment
438 0xdd, 0x02,
439 0xde, 0x00, // horizontal chrominance phase offset
440 0xdf, 0x00,
441 0xe0, 0x00, // vertical luminance scaling increment
442 0xe1, 0x04,
443 0xe2, 0x00, // vertical chrominance scaling increment
444 0xe3, 0x04,
445 0xe4, 0x00,
446 0xe5, 0x00,
447 0xe6, 0x00,
448 0xe7, 0x00,
449 0xe8, 0x00,
450 0xe9, 0x00,
451 0xea, 0x00,
452 0xeb, 0x00,
453 0xec, 0x00,
454 0xed, 0x00,
455 0xee, 0x00,
456 0xef, 0x00
459 static int
460 saa7114_command (struct i2c_client *client,
461 unsigned int cmd,
462 void *arg)
464 struct saa7114 *decoder = i2c_get_clientdata(client);
466 switch (cmd) {
468 case 0:
469 //dprintk(1, KERN_INFO "%s: writing init\n", I2C_NAME(client));
470 //saa7114_write_block(client, init, sizeof(init));
471 break;
473 case DECODER_DUMP:
475 int i;
477 dprintk(1, KERN_INFO "%s: decoder dump\n", I2C_NAME(client));
479 for (i = 0; i < 32; i += 16) {
480 int j;
482 printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i);
483 for (j = 0; j < 16; ++j) {
484 printk(" %02x",
485 saa7114_read(client, i + j));
487 printk("\n");
490 break;
492 case DECODER_GET_CAPABILITIES:
494 struct video_decoder_capability *cap = arg;
496 dprintk(1, KERN_DEBUG "%s: decoder get capabilities\n",
497 I2C_NAME(client));
499 cap->flags = VIDEO_DECODER_PAL |
500 VIDEO_DECODER_NTSC |
501 VIDEO_DECODER_AUTO |
502 VIDEO_DECODER_CCIR;
503 cap->inputs = 8;
504 cap->outputs = 1;
506 break;
508 case DECODER_GET_STATUS:
510 int *iarg = arg;
511 int status;
512 int res;
514 status = saa7114_read(client, 0x1f);
516 dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client),
517 status);
518 res = 0;
519 if ((status & (1 << 6)) == 0) {
520 res |= DECODER_STATUS_GOOD;
522 switch (decoder->norm) {
523 case VIDEO_MODE_NTSC:
524 res |= DECODER_STATUS_NTSC;
525 break;
526 case VIDEO_MODE_PAL:
527 res |= DECODER_STATUS_PAL;
528 break;
529 case VIDEO_MODE_SECAM:
530 res |= DECODER_STATUS_SECAM;
531 break;
532 default:
533 case VIDEO_MODE_AUTO:
534 if ((status & (1 << 5)) != 0) {
535 res |= DECODER_STATUS_NTSC;
536 } else {
537 res |= DECODER_STATUS_PAL;
539 break;
541 if ((status & (1 << 0)) != 0) {
542 res |= DECODER_STATUS_COLOR;
544 *iarg = res;
546 break;
548 case DECODER_SET_NORM:
550 int *iarg = arg;
552 short int hoff = 0, voff = 0, w = 0, h = 0;
554 dprintk(1, KERN_DEBUG "%s: decoder set norm ",
555 I2C_NAME(client));
556 switch (*iarg) {
558 case VIDEO_MODE_NTSC:
559 dprintk(1, "NTSC\n");
560 decoder->reg[REG_ADDR(0x06)] =
561 SAA_7114_NTSC_HSYNC_START;
562 decoder->reg[REG_ADDR(0x07)] =
563 SAA_7114_NTSC_HSYNC_STOP;
565 decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8; // PLL free when playback, PLL close when capture
567 decoder->reg[REG_ADDR(0x0e)] = 0x85;
568 decoder->reg[REG_ADDR(0x0f)] = 0x24;
570 hoff = SAA_7114_NTSC_HOFFSET;
571 voff = SAA_7114_NTSC_VOFFSET;
572 w = SAA_7114_NTSC_WIDTH;
573 h = SAA_7114_NTSC_HEIGHT;
575 break;
577 case VIDEO_MODE_PAL:
578 dprintk(1, "PAL\n");
579 decoder->reg[REG_ADDR(0x06)] =
580 SAA_7114_PAL_HSYNC_START;
581 decoder->reg[REG_ADDR(0x07)] =
582 SAA_7114_PAL_HSYNC_STOP;
584 decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8; // PLL free when playback, PLL close when capture
586 decoder->reg[REG_ADDR(0x0e)] = 0x81;
587 decoder->reg[REG_ADDR(0x0f)] = 0x24;
589 hoff = SAA_7114_PAL_HOFFSET;
590 voff = SAA_7114_PAL_VOFFSET;
591 w = SAA_7114_PAL_WIDTH;
592 h = SAA_7114_PAL_HEIGHT;
594 break;
596 default:
597 dprintk(1, " Unknown video mode!!!\n");
598 return -EINVAL;
603 decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff); // hoffset low
604 decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f; // hoffset high
605 decoder->reg[REG_ADDR(0x96)] = LOBYTE(w); // width low
606 decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f; // width high
607 decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff); // voffset low
608 decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f; // voffset high
609 decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2); // height low
610 decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f; // height high
611 decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w); // out width low
612 decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f; // out width high
613 decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h); // out height low
614 decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f; // out height high
616 decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff); // hoffset low
617 decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f; // hoffset high
618 decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w); // width low
619 decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f; // width high
620 decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff); // voffset low
621 decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f; // voffset high
622 decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2); // height low
623 decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f; // height high
624 decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w); // out width low
625 decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f; // out width high
626 decoder->reg[REG_ADDR(0xce)] = LOBYTE(h); // out height low
627 decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f; // out height high
630 saa7114_write(client, 0x80, 0x06); // i-port and scaler back end clock selection, task A&B off
631 saa7114_write(client, 0x88, 0xd8); // sw reset scaler
632 saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
634 saa7114_write_block(client, decoder->reg + (0x06 << 1),
635 3 << 1);
636 saa7114_write_block(client, decoder->reg + (0x0e << 1),
637 2 << 1);
638 saa7114_write_block(client, decoder->reg + (0x5a << 1),
639 2 << 1);
641 saa7114_write_block(client, decoder->reg + (0x94 << 1),
642 (0x9f + 1 - 0x94) << 1);
643 saa7114_write_block(client, decoder->reg + (0xc4 << 1),
644 (0xcf + 1 - 0xc4) << 1);
646 saa7114_write(client, 0x88, 0xd8); // sw reset scaler
647 saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
648 saa7114_write(client, 0x80, 0x36); // i-port and scaler back end clock selection
650 decoder->norm = *iarg;
652 break;
654 case DECODER_SET_INPUT:
656 int *iarg = arg;
658 dprintk(1, KERN_DEBUG "%s: decoder set input (%d)\n",
659 I2C_NAME(client), *iarg);
660 if (*iarg < 0 || *iarg > 7) {
661 return -EINVAL;
664 if (decoder->input != *iarg) {
665 dprintk(1, KERN_DEBUG "%s: now setting %s input\n",
666 I2C_NAME(client),
667 *iarg >= 6 ? "S-Video" : "Composite");
668 decoder->input = *iarg;
670 /* select mode */
671 decoder->reg[REG_ADDR(0x02)] =
672 (decoder->
673 reg[REG_ADDR(0x02)] & 0xf0) | (decoder->
674 input <
675 6 ? 0x0 : 0x9);
676 saa7114_write(client, 0x02,
677 decoder->reg[REG_ADDR(0x02)]);
679 /* bypass chrominance trap for modes 6..9 */
680 decoder->reg[REG_ADDR(0x09)] =
681 (decoder->
682 reg[REG_ADDR(0x09)] & 0x7f) | (decoder->
683 input <
684 6 ? 0x0 :
685 0x80);
686 saa7114_write(client, 0x09,
687 decoder->reg[REG_ADDR(0x09)]);
689 decoder->reg[REG_ADDR(0x0e)] =
690 decoder->input <
691 6 ? decoder->
692 reg[REG_ADDR(0x0e)] | 1 : decoder->
693 reg[REG_ADDR(0x0e)] & ~1;
694 saa7114_write(client, 0x0e,
695 decoder->reg[REG_ADDR(0x0e)]);
698 break;
700 case DECODER_SET_OUTPUT:
702 int *iarg = arg;
704 dprintk(1, KERN_DEBUG "%s: decoder set output\n",
705 I2C_NAME(client));
707 /* not much choice of outputs */
708 if (*iarg != 0) {
709 return -EINVAL;
712 break;
714 case DECODER_ENABLE_OUTPUT:
716 int *iarg = arg;
717 int enable = (*iarg != 0);
719 dprintk(1, KERN_DEBUG "%s: decoder %s output\n",
720 I2C_NAME(client), enable ? "enable" : "disable");
722 decoder->playback = !enable;
724 if (decoder->enable != enable) {
725 decoder->enable = enable;
727 /* RJ: If output should be disabled (for
728 * playing videos), we also need a open PLL.
729 * The input is set to 0 (where no input
730 * source is connected), although this
731 * is not necessary.
733 * If output should be enabled, we have to
734 * reverse the above.
737 if (decoder->enable) {
738 decoder->reg[REG_ADDR(0x08)] = 0xb8;
739 decoder->reg[REG_ADDR(0x12)] = 0xc9;
740 decoder->reg[REG_ADDR(0x13)] = 0x80;
741 decoder->reg[REG_ADDR(0x87)] = 0x01;
742 } else {
743 decoder->reg[REG_ADDR(0x08)] = 0x7c;
744 decoder->reg[REG_ADDR(0x12)] = 0x00;
745 decoder->reg[REG_ADDR(0x13)] = 0x00;
746 decoder->reg[REG_ADDR(0x87)] = 0x00;
749 saa7114_write_block(client,
750 decoder->reg + (0x12 << 1),
751 2 << 1);
752 saa7114_write(client, 0x08,
753 decoder->reg[REG_ADDR(0x08)]);
754 saa7114_write(client, 0x87,
755 decoder->reg[REG_ADDR(0x87)]);
756 saa7114_write(client, 0x88, 0xd8); // sw reset scaler
757 saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
758 saa7114_write(client, 0x80, 0x36);
762 break;
764 case DECODER_SET_PICTURE:
766 struct video_picture *pic = arg;
768 dprintk(1,
769 KERN_DEBUG
770 "%s: decoder set picture bright=%d contrast=%d saturation=%d hue=%d\n",
771 I2C_NAME(client), pic->brightness, pic->contrast,
772 pic->colour, pic->hue);
774 if (decoder->bright != pic->brightness) {
775 /* We want 0 to 255 we get 0-65535 */
776 decoder->bright = pic->brightness;
777 saa7114_write(client, 0x0a, decoder->bright >> 8);
779 if (decoder->contrast != pic->contrast) {
780 /* We want 0 to 127 we get 0-65535 */
781 decoder->contrast = pic->contrast;
782 saa7114_write(client, 0x0b,
783 decoder->contrast >> 9);
785 if (decoder->sat != pic->colour) {
786 /* We want 0 to 127 we get 0-65535 */
787 decoder->sat = pic->colour;
788 saa7114_write(client, 0x0c, decoder->sat >> 9);
790 if (decoder->hue != pic->hue) {
791 /* We want -128 to 127 we get 0-65535 */
792 decoder->hue = pic->hue;
793 saa7114_write(client, 0x0d,
794 (decoder->hue - 32768) >> 8);
797 break;
799 default:
800 return -EINVAL;
803 return 0;
806 /* ----------------------------------------------------------------------- */
809 * Generic i2c probe
810 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
812 static unsigned short normal_i2c[] =
813 { I2C_SAA7114 >> 1, I2C_SAA7114A >> 1, I2C_CLIENT_END };
815 static unsigned short ignore = I2C_CLIENT_END;
817 static struct i2c_client_address_data addr_data = {
818 .normal_i2c = normal_i2c,
819 .probe = &ignore,
820 .ignore = &ignore,
823 static struct i2c_driver i2c_driver_saa7114;
825 static int
826 saa7114_detect_client (struct i2c_adapter *adapter,
827 int address,
828 int kind)
830 int i, err[30];
831 short int hoff = SAA_7114_NTSC_HOFFSET;
832 short int voff = SAA_7114_NTSC_VOFFSET;
833 short int w = SAA_7114_NTSC_WIDTH;
834 short int h = SAA_7114_NTSC_HEIGHT;
835 struct i2c_client *client;
836 struct saa7114 *decoder;
838 dprintk(1,
839 KERN_INFO
840 "saa7114.c: detecting saa7114 client on address 0x%x\n",
841 address << 1);
843 /* Check if the adapter supports the needed features */
844 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
845 return 0;
847 client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
848 if (client == 0)
849 return -ENOMEM;
850 client->addr = address;
851 client->adapter = adapter;
852 client->driver = &i2c_driver_saa7114;
853 strlcpy(I2C_NAME(client), "saa7114", sizeof(I2C_NAME(client)));
855 decoder = kzalloc(sizeof(struct saa7114), GFP_KERNEL);
856 if (decoder == NULL) {
857 kfree(client);
858 return -ENOMEM;
860 decoder->norm = VIDEO_MODE_NTSC;
861 decoder->input = -1;
862 decoder->enable = 1;
863 decoder->bright = 32768;
864 decoder->contrast = 32768;
865 decoder->hue = 32768;
866 decoder->sat = 32768;
867 decoder->playback = 0; // initially capture mode useda
868 i2c_set_clientdata(client, decoder);
870 memcpy(decoder->reg, init, sizeof(init));
872 decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff); // hoffset low
873 decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f; // hoffset high
874 decoder->reg[REG_ADDR(0x96)] = LOBYTE(w); // width low
875 decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f; // width high
876 decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff); // voffset low
877 decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f; // voffset high
878 decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2); // height low
879 decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f; // height high
880 decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w); // out width low
881 decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f; // out width high
882 decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h); // out height low
883 decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f; // out height high
885 decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff); // hoffset low
886 decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f; // hoffset high
887 decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w); // width low
888 decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f; // width high
889 decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff); // voffset low
890 decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f; // voffset high
891 decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2); // height low
892 decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f; // height high
893 decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w); // out width low
894 decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f; // out width high
895 decoder->reg[REG_ADDR(0xce)] = LOBYTE(h); // out height low
896 decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f; // out height high
898 decoder->reg[REG_ADDR(0xb8)] =
899 LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
900 decoder->reg[REG_ADDR(0xb9)] =
901 HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
902 decoder->reg[REG_ADDR(0xba)] =
903 LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
904 decoder->reg[REG_ADDR(0xbb)] =
905 HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
907 decoder->reg[REG_ADDR(0xbc)] =
908 LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
909 decoder->reg[REG_ADDR(0xbd)] =
910 HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
911 decoder->reg[REG_ADDR(0xbe)] =
912 LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
913 decoder->reg[REG_ADDR(0xbf)] =
914 HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
916 decoder->reg[REG_ADDR(0xe8)] =
917 LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
918 decoder->reg[REG_ADDR(0xe9)] =
919 HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
920 decoder->reg[REG_ADDR(0xea)] =
921 LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
922 decoder->reg[REG_ADDR(0xeb)] =
923 HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
925 decoder->reg[REG_ADDR(0xec)] =
926 LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
927 decoder->reg[REG_ADDR(0xed)] =
928 HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
929 decoder->reg[REG_ADDR(0xee)] =
930 LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
931 decoder->reg[REG_ADDR(0xef)] =
932 HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
935 decoder->reg[REG_ADDR(0x13)] = 0x80; // RTC0 on
936 decoder->reg[REG_ADDR(0x87)] = 0x01; // I-Port
937 decoder->reg[REG_ADDR(0x12)] = 0xc9; // RTS0
939 decoder->reg[REG_ADDR(0x02)] = 0xc0; // set composite1 input, aveasy
940 decoder->reg[REG_ADDR(0x09)] = 0x00; // chrominance trap
941 decoder->reg[REG_ADDR(0x0e)] |= 1; // combfilter on
944 dprintk(1, KERN_DEBUG "%s_attach: starting decoder init\n",
945 I2C_NAME(client));
947 err[0] =
948 saa7114_write_block(client, decoder->reg + (0x20 << 1),
949 0x10 << 1);
950 err[1] =
951 saa7114_write_block(client, decoder->reg + (0x30 << 1),
952 0x10 << 1);
953 err[2] =
954 saa7114_write_block(client, decoder->reg + (0x63 << 1),
955 (0x7f + 1 - 0x63) << 1);
956 err[3] =
957 saa7114_write_block(client, decoder->reg + (0x89 << 1),
958 6 << 1);
959 err[4] =
960 saa7114_write_block(client, decoder->reg + (0xb8 << 1),
961 8 << 1);
962 err[5] =
963 saa7114_write_block(client, decoder->reg + (0xe8 << 1),
964 8 << 1);
967 for (i = 0; i <= 5; i++) {
968 if (err[i] < 0) {
969 dprintk(1,
970 KERN_ERR
971 "%s_attach: init error %d at stage %d, leaving attach.\n",
972 I2C_NAME(client), i, err[i]);
973 kfree(decoder);
974 kfree(client);
975 return 0;
979 for (i = 6; i < 8; i++) {
980 dprintk(1,
981 KERN_DEBUG
982 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
983 I2C_NAME(client), i, saa7114_read(client, i),
984 decoder->reg[REG_ADDR(i)]);
987 dprintk(1,
988 KERN_DEBUG
989 "%s_attach: performing decoder reset sequence\n",
990 I2C_NAME(client));
992 err[6] = saa7114_write(client, 0x80, 0x06); // i-port and scaler backend clock selection, task A&B off
993 err[7] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler
994 err[8] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
996 for (i = 6; i <= 8; i++) {
997 if (err[i] < 0) {
998 dprintk(1,
999 KERN_ERR
1000 "%s_attach: init error %d at stage %d, leaving attach.\n",
1001 I2C_NAME(client), i, err[i]);
1002 kfree(decoder);
1003 kfree(client);
1004 return 0;
1008 dprintk(1, KERN_INFO "%s_attach: performing the rest of init\n",
1009 I2C_NAME(client));
1012 err[9] = saa7114_write(client, 0x01, decoder->reg[REG_ADDR(0x01)]);
1013 err[10] = saa7114_write_block(client, decoder->reg + (0x03 << 1), (0x1e + 1 - 0x03) << 1); // big seq
1014 err[11] = saa7114_write_block(client, decoder->reg + (0x40 << 1), (0x5f + 1 - 0x40) << 1); // slicer
1015 err[12] = saa7114_write_block(client, decoder->reg + (0x81 << 1), 2 << 1); // ?
1016 err[13] = saa7114_write_block(client, decoder->reg + (0x83 << 1), 5 << 1); // ?
1017 err[14] = saa7114_write_block(client, decoder->reg + (0x90 << 1), 4 << 1); // Task A
1018 err[15] =
1019 saa7114_write_block(client, decoder->reg + (0x94 << 1),
1020 12 << 1);
1021 err[16] =
1022 saa7114_write_block(client, decoder->reg + (0xa0 << 1),
1023 8 << 1);
1024 err[17] =
1025 saa7114_write_block(client, decoder->reg + (0xa8 << 1),
1026 8 << 1);
1027 err[18] =
1028 saa7114_write_block(client, decoder->reg + (0xb0 << 1),
1029 8 << 1);
1030 err[19] = saa7114_write_block(client, decoder->reg + (0xc0 << 1), 4 << 1); // Task B
1031 err[15] =
1032 saa7114_write_block(client, decoder->reg + (0xc4 << 1),
1033 12 << 1);
1034 err[16] =
1035 saa7114_write_block(client, decoder->reg + (0xd0 << 1),
1036 8 << 1);
1037 err[17] =
1038 saa7114_write_block(client, decoder->reg + (0xd8 << 1),
1039 8 << 1);
1040 err[18] =
1041 saa7114_write_block(client, decoder->reg + (0xe0 << 1),
1042 8 << 1);
1044 for (i = 9; i <= 18; i++) {
1045 if (err[i] < 0) {
1046 dprintk(1,
1047 KERN_ERR
1048 "%s_attach: init error %d at stage %d, leaving attach.\n",
1049 I2C_NAME(client), i, err[i]);
1050 kfree(decoder);
1051 kfree(client);
1052 return 0;
1057 for (i = 6; i < 8; i++) {
1058 dprintk(1,
1059 KERN_DEBUG
1060 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
1061 I2C_NAME(client), i, saa7114_read(client, i),
1062 decoder->reg[REG_ADDR(i)]);
1066 for (i = 0x11; i <= 0x13; i++) {
1067 dprintk(1,
1068 KERN_DEBUG
1069 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
1070 I2C_NAME(client), i, saa7114_read(client, i),
1071 decoder->reg[REG_ADDR(i)]);
1075 dprintk(1, KERN_DEBUG "%s_attach: setting video input\n",
1076 I2C_NAME(client));
1078 err[19] =
1079 saa7114_write(client, 0x02, decoder->reg[REG_ADDR(0x02)]);
1080 err[20] =
1081 saa7114_write(client, 0x09, decoder->reg[REG_ADDR(0x09)]);
1082 err[21] =
1083 saa7114_write(client, 0x0e, decoder->reg[REG_ADDR(0x0e)]);
1085 for (i = 19; i <= 21; i++) {
1086 if (err[i] < 0) {
1087 dprintk(1,
1088 KERN_ERR
1089 "%s_attach: init error %d at stage %d, leaving attach.\n",
1090 I2C_NAME(client), i, err[i]);
1091 kfree(decoder);
1092 kfree(client);
1093 return 0;
1097 dprintk(1,
1098 KERN_DEBUG
1099 "%s_attach: performing decoder reset sequence\n",
1100 I2C_NAME(client));
1102 err[22] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler
1103 err[23] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
1104 err[24] = saa7114_write(client, 0x80, 0x36); // i-port and scaler backend clock selection, task A&B off
1107 for (i = 22; i <= 24; i++) {
1108 if (err[i] < 0) {
1109 dprintk(1,
1110 KERN_ERR
1111 "%s_attach: init error %d at stage %d, leaving attach.\n",
1112 I2C_NAME(client), i, err[i]);
1113 kfree(decoder);
1114 kfree(client);
1115 return 0;
1119 err[25] = saa7114_write(client, 0x06, init[REG_ADDR(0x06)]);
1120 err[26] = saa7114_write(client, 0x07, init[REG_ADDR(0x07)]);
1121 err[27] = saa7114_write(client, 0x10, init[REG_ADDR(0x10)]);
1123 dprintk(1,
1124 KERN_INFO
1125 "%s_attach: chip version %x, decoder status 0x%02x\n",
1126 I2C_NAME(client), saa7114_read(client, 0x00) >> 4,
1127 saa7114_read(client, 0x1f));
1128 dprintk(1,
1129 KERN_DEBUG
1130 "%s_attach: power save control: 0x%02x, scaler status: 0x%02x\n",
1131 I2C_NAME(client), saa7114_read(client, 0x88),
1132 saa7114_read(client, 0x8f));
1135 for (i = 0x94; i < 0x96; i++) {
1136 dprintk(1,
1137 KERN_DEBUG
1138 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
1139 I2C_NAME(client), i, saa7114_read(client, i),
1140 decoder->reg[REG_ADDR(i)]);
1143 i = i2c_attach_client(client);
1144 if (i) {
1145 kfree(client);
1146 kfree(decoder);
1147 return i;
1150 //i = saa7114_write_block(client, init, sizeof(init));
1151 i = 0;
1152 if (i < 0) {
1153 dprintk(1, KERN_ERR "%s_attach error: init status %d\n",
1154 I2C_NAME(client), i);
1155 } else {
1156 dprintk(1,
1157 KERN_INFO
1158 "%s_attach: chip version %x at address 0x%x\n",
1159 I2C_NAME(client), saa7114_read(client, 0x00) >> 4,
1160 client->addr << 1);
1163 return 0;
1166 static int
1167 saa7114_attach_adapter (struct i2c_adapter *adapter)
1169 dprintk(1,
1170 KERN_INFO
1171 "saa7114.c: starting probe for adapter %s (0x%x)\n",
1172 I2C_NAME(adapter), adapter->id);
1173 return i2c_probe(adapter, &addr_data, &saa7114_detect_client);
1176 static int
1177 saa7114_detach_client (struct i2c_client *client)
1179 struct saa7114 *decoder = i2c_get_clientdata(client);
1180 int err;
1182 err = i2c_detach_client(client);
1183 if (err) {
1184 return err;
1187 kfree(decoder);
1188 kfree(client);
1190 return 0;
1193 /* ----------------------------------------------------------------------- */
1195 static struct i2c_driver i2c_driver_saa7114 = {
1196 .driver = {
1197 .name = "saa7114",
1200 .id = I2C_DRIVERID_SAA7114,
1202 .attach_adapter = saa7114_attach_adapter,
1203 .detach_client = saa7114_detach_client,
1204 .command = saa7114_command,
1207 static int __init
1208 saa7114_init (void)
1210 return i2c_add_driver(&i2c_driver_saa7114);
1213 static void __exit
1214 saa7114_exit (void)
1216 i2c_del_driver(&i2c_driver_saa7114);
1219 module_init(saa7114_init);
1220 module_exit(saa7114_exit);