natsemi: Support Aculab E1/T1 PMXc cPCI carrier cards
[linux-2.6/openmoko-kernel/knife-kernel.git] / drivers / media / video / saa7114.c
blob2ce3321ab995032d7ae1c932fcacc458c7856670
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/types.h>
49 #include <linux/videodev.h>
50 #include <asm/uaccess.h>
52 MODULE_DESCRIPTION("Philips SAA7114H video decoder driver");
53 MODULE_AUTHOR("Maxim Yevtyushkin");
54 MODULE_LICENSE("GPL");
56 #include <linux/i2c.h>
58 #define I2C_NAME(x) (x)->name
60 #include <linux/video_decoder.h>
62 static int debug = 0;
63 module_param(debug, int, 0);
64 MODULE_PARM_DESC(debug, "Debug level (0-1)");
66 #define dprintk(num, format, args...) \
67 do { \
68 if (debug >= num) \
69 printk(format, ##args); \
70 } while (0)
72 /* ----------------------------------------------------------------------- */
74 struct saa7114 {
75 unsigned char reg[0xf0 * 2];
77 int norm;
78 int input;
79 int enable;
80 int bright;
81 int contrast;
82 int hue;
83 int sat;
84 int playback;
87 #define I2C_SAA7114 0x42
88 #define I2C_SAA7114A 0x40
90 #define I2C_DELAY 10
93 //#define SAA_7114_NTSC_HSYNC_START (-3)
94 //#define SAA_7114_NTSC_HSYNC_STOP (-18)
96 #define SAA_7114_NTSC_HSYNC_START (-17)
97 #define SAA_7114_NTSC_HSYNC_STOP (-32)
99 //#define SAA_7114_NTSC_HOFFSET (5)
100 #define SAA_7114_NTSC_HOFFSET (6)
101 #define SAA_7114_NTSC_VOFFSET (10)
102 #define SAA_7114_NTSC_WIDTH (720)
103 #define SAA_7114_NTSC_HEIGHT (250)
105 #define SAA_7114_SECAM_HSYNC_START (-17)
106 #define SAA_7114_SECAM_HSYNC_STOP (-32)
108 #define SAA_7114_SECAM_HOFFSET (2)
109 #define SAA_7114_SECAM_VOFFSET (10)
110 #define SAA_7114_SECAM_WIDTH (720)
111 #define SAA_7114_SECAM_HEIGHT (300)
113 #define SAA_7114_PAL_HSYNC_START (-17)
114 #define SAA_7114_PAL_HSYNC_STOP (-32)
116 #define SAA_7114_PAL_HOFFSET (2)
117 #define SAA_7114_PAL_VOFFSET (10)
118 #define SAA_7114_PAL_WIDTH (720)
119 #define SAA_7114_PAL_HEIGHT (300)
123 #define SAA_7114_VERTICAL_CHROMA_OFFSET 0 //0x50504040
124 #define SAA_7114_VERTICAL_LUMA_OFFSET 0
126 #define REG_ADDR(x) (((x) << 1) + 1)
127 #define LOBYTE(x) ((unsigned char)((x) & 0xff))
128 #define HIBYTE(x) ((unsigned char)(((x) >> 8) & 0xff))
129 #define LOWORD(x) ((unsigned short int)((x) & 0xffff))
130 #define HIWORD(x) ((unsigned short int)(((x) >> 16) & 0xffff))
133 /* ----------------------------------------------------------------------- */
135 static inline int
136 saa7114_write (struct i2c_client *client,
137 u8 reg,
138 u8 value)
140 return i2c_smbus_write_byte_data(client, reg, value);
143 static int
144 saa7114_write_block (struct i2c_client *client,
145 const u8 *data,
146 unsigned int len)
148 int ret = -1;
149 u8 reg;
151 /* the saa7114 has an autoincrement function, use it if
152 * the adapter understands raw I2C */
153 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
154 /* do raw I2C, not smbus compatible */
155 u8 block_data[32];
156 int block_len;
158 while (len >= 2) {
159 block_len = 0;
160 block_data[block_len++] = reg = data[0];
161 do {
162 block_data[block_len++] = data[1];
163 reg++;
164 len -= 2;
165 data += 2;
166 } while (len >= 2 && data[0] == reg &&
167 block_len < 32);
168 if ((ret = i2c_master_send(client, block_data,
169 block_len)) < 0)
170 break;
172 } else {
173 /* do some slow I2C emulation kind of thing */
174 while (len >= 2) {
175 reg = *data++;
176 if ((ret = saa7114_write(client, reg,
177 *data++)) < 0)
178 break;
179 len -= 2;
183 return ret;
186 static inline int
187 saa7114_read (struct i2c_client *client,
188 u8 reg)
190 return i2c_smbus_read_byte_data(client, reg);
193 /* ----------------------------------------------------------------------- */
195 // initially set NTSC, composite
198 static const unsigned char init[] = {
199 0x00, 0x00, /* 00 - ID byte , chip version,
200 * read only */
201 0x01, 0x08, /* 01 - X,X,X,X, IDEL3 to IDEL0 -
202 * horizontal increment delay,
203 * recommended position */
204 0x02, 0x00, /* 02 - FUSE=3, GUDL=2, MODE=0 ;
205 * input control */
206 0x03, 0x10, /* 03 - HLNRS=0, VBSL=1, WPOFF=0,
207 * HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
208 0x04, 0x90, /* 04 - GAI1=256 */
209 0x05, 0x90, /* 05 - GAI2=256 */
210 0x06, SAA_7114_NTSC_HSYNC_START, /* 06 - HSB: hsync start,
211 * depends on the video standard */
212 0x07, SAA_7114_NTSC_HSYNC_STOP, /* 07 - HSS: hsync stop, depends
213 *on the video standard */
214 0x08, 0xb8, /* 08 - AUFD=1, FSEL=1, EXFIL=0, VTRC=1,
215 * HPLL: free running in playback, locked
216 * in capture, VNOI=0 */
217 0x09, 0x80, /* 09 - BYPS=0, PREF=0, BPSS=0, VBLB=0,
218 * UPTCV=0, APER=1; depends from input */
219 0x0a, 0x80, /* 0a - BRIG=128 */
220 0x0b, 0x44, /* 0b - CONT=1.109 */
221 0x0c, 0x40, /* 0c - SATN=1.0 */
222 0x0d, 0x00, /* 0d - HUE=0 */
223 0x0e, 0x84, /* 0e - CDTO, CSTD2 to 0, DCVF, FCTC,
224 * CCOMB; depends from video standard */
225 0x0f, 0x24, /* 0f - ACGC,CGAIN6 to CGAIN0; depends
226 * from video standard */
227 0x10, 0x03, /* 10 - OFFU1 to 0, OFFV1 to 0, CHBW,
228 * LCBW2 to 0 */
229 0x11, 0x59, /* 11 - COLO, RTP1, HEDL1 to 0, RTP0,
230 * YDEL2 to 0 */
231 0x12, 0xc9, /* 12 - RT signal control RTSE13 to 10
232 * and 03 to 00 */
233 0x13, 0x80, /* 13 - RT/X port output control */
234 0x14, 0x00, /* 14 - analog, ADC, compatibility control */
235 0x15, 0x00, /* 15 - VGATE start FID change */
236 0x16, 0xfe, /* 16 - VGATE stop */
237 0x17, 0x00, /* 17 - Misc., VGATE MSBs */
238 0x18, 0x40, /* RAWG */
239 0x19, 0x80, /* RAWO */
240 0x1a, 0x00,
241 0x1b, 0x00,
242 0x1c, 0x00,
243 0x1d, 0x00,
244 0x1e, 0x00,
245 0x1f, 0x00, /* status byte, read only */
246 0x20, 0x00, /* video decoder reserved part */
247 0x21, 0x00,
248 0x22, 0x00,
249 0x23, 0x00,
250 0x24, 0x00,
251 0x25, 0x00,
252 0x26, 0x00,
253 0x27, 0x00,
254 0x28, 0x00,
255 0x29, 0x00,
256 0x2a, 0x00,
257 0x2b, 0x00,
258 0x2c, 0x00,
259 0x2d, 0x00,
260 0x2e, 0x00,
261 0x2f, 0x00,
262 0x30, 0xbc, /* audio clock generator */
263 0x31, 0xdf,
264 0x32, 0x02,
265 0x33, 0x00,
266 0x34, 0xcd,
267 0x35, 0xcc,
268 0x36, 0x3a,
269 0x37, 0x00,
270 0x38, 0x03,
271 0x39, 0x10,
272 0x3a, 0x00,
273 0x3b, 0x00,
274 0x3c, 0x00,
275 0x3d, 0x00,
276 0x3e, 0x00,
277 0x3f, 0x00,
278 0x40, 0x00, /* VBI data slicer */
279 0x41, 0xff,
280 0x42, 0xff,
281 0x43, 0xff,
282 0x44, 0xff,
283 0x45, 0xff,
284 0x46, 0xff,
285 0x47, 0xff,
286 0x48, 0xff,
287 0x49, 0xff,
288 0x4a, 0xff,
289 0x4b, 0xff,
290 0x4c, 0xff,
291 0x4d, 0xff,
292 0x4e, 0xff,
293 0x4f, 0xff,
294 0x50, 0xff,
295 0x51, 0xff,
296 0x52, 0xff,
297 0x53, 0xff,
298 0x54, 0xff,
299 0x55, 0xff,
300 0x56, 0xff,
301 0x57, 0xff,
302 0x58, 0x40, // framing code
303 0x59, 0x47, // horizontal offset
304 0x5a, 0x06, // vertical offset
305 0x5b, 0x83, // field offset
306 0x5c, 0x00, // reserved
307 0x5d, 0x3e, // header and data
308 0x5e, 0x00, // sliced data
309 0x5f, 0x00, // reserved
310 0x60, 0x00, /* video decoder reserved part */
311 0x61, 0x00,
312 0x62, 0x00,
313 0x63, 0x00,
314 0x64, 0x00,
315 0x65, 0x00,
316 0x66, 0x00,
317 0x67, 0x00,
318 0x68, 0x00,
319 0x69, 0x00,
320 0x6a, 0x00,
321 0x6b, 0x00,
322 0x6c, 0x00,
323 0x6d, 0x00,
324 0x6e, 0x00,
325 0x6f, 0x00,
326 0x70, 0x00, /* video decoder reserved part */
327 0x71, 0x00,
328 0x72, 0x00,
329 0x73, 0x00,
330 0x74, 0x00,
331 0x75, 0x00,
332 0x76, 0x00,
333 0x77, 0x00,
334 0x78, 0x00,
335 0x79, 0x00,
336 0x7a, 0x00,
337 0x7b, 0x00,
338 0x7c, 0x00,
339 0x7d, 0x00,
340 0x7e, 0x00,
341 0x7f, 0x00,
342 0x80, 0x00, /* X-port, I-port and scaler */
343 0x81, 0x00,
344 0x82, 0x00,
345 0x83, 0x00,
346 0x84, 0xc5,
347 0x85, 0x0d, // hsync and vsync ?
348 0x86, 0x40,
349 0x87, 0x01,
350 0x88, 0x00,
351 0x89, 0x00,
352 0x8a, 0x00,
353 0x8b, 0x00,
354 0x8c, 0x00,
355 0x8d, 0x00,
356 0x8e, 0x00,
357 0x8f, 0x00,
358 0x90, 0x03, /* Task A definition */
359 0x91, 0x08,
360 0x92, 0x00,
361 0x93, 0x40,
362 0x94, 0x00, // window settings
363 0x95, 0x00,
364 0x96, 0x00,
365 0x97, 0x00,
366 0x98, 0x00,
367 0x99, 0x00,
368 0x9a, 0x00,
369 0x9b, 0x00,
370 0x9c, 0x00,
371 0x9d, 0x00,
372 0x9e, 0x00,
373 0x9f, 0x00,
374 0xa0, 0x01, /* horizontal integer prescaling ratio */
375 0xa1, 0x00, /* horizontal prescaler accumulation
376 * sequence length */
377 0xa2, 0x00, /* UV FIR filter, Y FIR filter, prescaler
378 * DC gain */
379 0xa3, 0x00,
380 0xa4, 0x80, // luminance brightness
381 0xa5, 0x40, // luminance gain
382 0xa6, 0x40, // chrominance saturation
383 0xa7, 0x00,
384 0xa8, 0x00, // horizontal luminance scaling increment
385 0xa9, 0x04,
386 0xaa, 0x00, // horizontal luminance phase offset
387 0xab, 0x00,
388 0xac, 0x00, // horizontal chrominance scaling increment
389 0xad, 0x02,
390 0xae, 0x00, // horizontal chrominance phase offset
391 0xaf, 0x00,
392 0xb0, 0x00, // vertical luminance scaling increment
393 0xb1, 0x04,
394 0xb2, 0x00, // vertical chrominance scaling increment
395 0xb3, 0x04,
396 0xb4, 0x00,
397 0xb5, 0x00,
398 0xb6, 0x00,
399 0xb7, 0x00,
400 0xb8, 0x00,
401 0xb9, 0x00,
402 0xba, 0x00,
403 0xbb, 0x00,
404 0xbc, 0x00,
405 0xbd, 0x00,
406 0xbe, 0x00,
407 0xbf, 0x00,
408 0xc0, 0x02, // Task B definition
409 0xc1, 0x08,
410 0xc2, 0x00,
411 0xc3, 0x40,
412 0xc4, 0x00, // window settings
413 0xc5, 0x00,
414 0xc6, 0x00,
415 0xc7, 0x00,
416 0xc8, 0x00,
417 0xc9, 0x00,
418 0xca, 0x00,
419 0xcb, 0x00,
420 0xcc, 0x00,
421 0xcd, 0x00,
422 0xce, 0x00,
423 0xcf, 0x00,
424 0xd0, 0x01, // horizontal integer prescaling ratio
425 0xd1, 0x00, // horizontal prescaler accumulation sequence length
426 0xd2, 0x00, // UV FIR filter, Y FIR filter, prescaler DC gain
427 0xd3, 0x00,
428 0xd4, 0x80, // luminance brightness
429 0xd5, 0x40, // luminance gain
430 0xd6, 0x40, // chrominance saturation
431 0xd7, 0x00,
432 0xd8, 0x00, // horizontal luminance scaling increment
433 0xd9, 0x04,
434 0xda, 0x00, // horizontal luminance phase offset
435 0xdb, 0x00,
436 0xdc, 0x00, // horizontal chrominance scaling increment
437 0xdd, 0x02,
438 0xde, 0x00, // horizontal chrominance phase offset
439 0xdf, 0x00,
440 0xe0, 0x00, // vertical luminance scaling increment
441 0xe1, 0x04,
442 0xe2, 0x00, // vertical chrominance scaling increment
443 0xe3, 0x04,
444 0xe4, 0x00,
445 0xe5, 0x00,
446 0xe6, 0x00,
447 0xe7, 0x00,
448 0xe8, 0x00,
449 0xe9, 0x00,
450 0xea, 0x00,
451 0xeb, 0x00,
452 0xec, 0x00,
453 0xed, 0x00,
454 0xee, 0x00,
455 0xef, 0x00
458 static int
459 saa7114_command (struct i2c_client *client,
460 unsigned int cmd,
461 void *arg)
463 struct saa7114 *decoder = i2c_get_clientdata(client);
465 switch (cmd) {
467 case 0:
468 //dprintk(1, KERN_INFO "%s: writing init\n", I2C_NAME(client));
469 //saa7114_write_block(client, init, sizeof(init));
470 break;
472 case DECODER_DUMP:
474 int i;
476 dprintk(1, KERN_INFO "%s: decoder dump\n", I2C_NAME(client));
478 for (i = 0; i < 32; i += 16) {
479 int j;
481 printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i);
482 for (j = 0; j < 16; ++j) {
483 printk(" %02x",
484 saa7114_read(client, i + j));
486 printk("\n");
489 break;
491 case DECODER_GET_CAPABILITIES:
493 struct video_decoder_capability *cap = arg;
495 dprintk(1, KERN_DEBUG "%s: decoder get capabilities\n",
496 I2C_NAME(client));
498 cap->flags = VIDEO_DECODER_PAL |
499 VIDEO_DECODER_NTSC |
500 VIDEO_DECODER_AUTO |
501 VIDEO_DECODER_CCIR;
502 cap->inputs = 8;
503 cap->outputs = 1;
505 break;
507 case DECODER_GET_STATUS:
509 int *iarg = arg;
510 int status;
511 int res;
513 status = saa7114_read(client, 0x1f);
515 dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client),
516 status);
517 res = 0;
518 if ((status & (1 << 6)) == 0) {
519 res |= DECODER_STATUS_GOOD;
521 switch (decoder->norm) {
522 case VIDEO_MODE_NTSC:
523 res |= DECODER_STATUS_NTSC;
524 break;
525 case VIDEO_MODE_PAL:
526 res |= DECODER_STATUS_PAL;
527 break;
528 case VIDEO_MODE_SECAM:
529 res |= DECODER_STATUS_SECAM;
530 break;
531 default:
532 case VIDEO_MODE_AUTO:
533 if ((status & (1 << 5)) != 0) {
534 res |= DECODER_STATUS_NTSC;
535 } else {
536 res |= DECODER_STATUS_PAL;
538 break;
540 if ((status & (1 << 0)) != 0) {
541 res |= DECODER_STATUS_COLOR;
543 *iarg = res;
545 break;
547 case DECODER_SET_NORM:
549 int *iarg = arg;
551 short int hoff = 0, voff = 0, w = 0, h = 0;
553 dprintk(1, KERN_DEBUG "%s: decoder set norm ",
554 I2C_NAME(client));
555 switch (*iarg) {
557 case VIDEO_MODE_NTSC:
558 dprintk(1, "NTSC\n");
559 decoder->reg[REG_ADDR(0x06)] =
560 SAA_7114_NTSC_HSYNC_START;
561 decoder->reg[REG_ADDR(0x07)] =
562 SAA_7114_NTSC_HSYNC_STOP;
564 decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8; // PLL free when playback, PLL close when capture
566 decoder->reg[REG_ADDR(0x0e)] = 0x85;
567 decoder->reg[REG_ADDR(0x0f)] = 0x24;
569 hoff = SAA_7114_NTSC_HOFFSET;
570 voff = SAA_7114_NTSC_VOFFSET;
571 w = SAA_7114_NTSC_WIDTH;
572 h = SAA_7114_NTSC_HEIGHT;
574 break;
576 case VIDEO_MODE_PAL:
577 dprintk(1, "PAL\n");
578 decoder->reg[REG_ADDR(0x06)] =
579 SAA_7114_PAL_HSYNC_START;
580 decoder->reg[REG_ADDR(0x07)] =
581 SAA_7114_PAL_HSYNC_STOP;
583 decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8; // PLL free when playback, PLL close when capture
585 decoder->reg[REG_ADDR(0x0e)] = 0x81;
586 decoder->reg[REG_ADDR(0x0f)] = 0x24;
588 hoff = SAA_7114_PAL_HOFFSET;
589 voff = SAA_7114_PAL_VOFFSET;
590 w = SAA_7114_PAL_WIDTH;
591 h = SAA_7114_PAL_HEIGHT;
593 break;
595 default:
596 dprintk(1, " Unknown video mode!!!\n");
597 return -EINVAL;
602 decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff); // hoffset low
603 decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f; // hoffset high
604 decoder->reg[REG_ADDR(0x96)] = LOBYTE(w); // width low
605 decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f; // width high
606 decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff); // voffset low
607 decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f; // voffset high
608 decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2); // height low
609 decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f; // height high
610 decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w); // out width low
611 decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f; // out width high
612 decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h); // out height low
613 decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f; // out height high
615 decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff); // hoffset low
616 decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f; // hoffset high
617 decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w); // width low
618 decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f; // width high
619 decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff); // voffset low
620 decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f; // voffset high
621 decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2); // height low
622 decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f; // height high
623 decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w); // out width low
624 decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f; // out width high
625 decoder->reg[REG_ADDR(0xce)] = LOBYTE(h); // out height low
626 decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f; // out height high
629 saa7114_write(client, 0x80, 0x06); // i-port and scaler back end clock selection, task A&B off
630 saa7114_write(client, 0x88, 0xd8); // sw reset scaler
631 saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
633 saa7114_write_block(client, decoder->reg + (0x06 << 1),
634 3 << 1);
635 saa7114_write_block(client, decoder->reg + (0x0e << 1),
636 2 << 1);
637 saa7114_write_block(client, decoder->reg + (0x5a << 1),
638 2 << 1);
640 saa7114_write_block(client, decoder->reg + (0x94 << 1),
641 (0x9f + 1 - 0x94) << 1);
642 saa7114_write_block(client, decoder->reg + (0xc4 << 1),
643 (0xcf + 1 - 0xc4) << 1);
645 saa7114_write(client, 0x88, 0xd8); // sw reset scaler
646 saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
647 saa7114_write(client, 0x80, 0x36); // i-port and scaler back end clock selection
649 decoder->norm = *iarg;
651 break;
653 case DECODER_SET_INPUT:
655 int *iarg = arg;
657 dprintk(1, KERN_DEBUG "%s: decoder set input (%d)\n",
658 I2C_NAME(client), *iarg);
659 if (*iarg < 0 || *iarg > 7) {
660 return -EINVAL;
663 if (decoder->input != *iarg) {
664 dprintk(1, KERN_DEBUG "%s: now setting %s input\n",
665 I2C_NAME(client),
666 *iarg >= 6 ? "S-Video" : "Composite");
667 decoder->input = *iarg;
669 /* select mode */
670 decoder->reg[REG_ADDR(0x02)] =
671 (decoder->
672 reg[REG_ADDR(0x02)] & 0xf0) | (decoder->
673 input <
674 6 ? 0x0 : 0x9);
675 saa7114_write(client, 0x02,
676 decoder->reg[REG_ADDR(0x02)]);
678 /* bypass chrominance trap for modes 6..9 */
679 decoder->reg[REG_ADDR(0x09)] =
680 (decoder->
681 reg[REG_ADDR(0x09)] & 0x7f) | (decoder->
682 input <
683 6 ? 0x0 :
684 0x80);
685 saa7114_write(client, 0x09,
686 decoder->reg[REG_ADDR(0x09)]);
688 decoder->reg[REG_ADDR(0x0e)] =
689 decoder->input <
690 6 ? decoder->
691 reg[REG_ADDR(0x0e)] | 1 : decoder->
692 reg[REG_ADDR(0x0e)] & ~1;
693 saa7114_write(client, 0x0e,
694 decoder->reg[REG_ADDR(0x0e)]);
697 break;
699 case DECODER_SET_OUTPUT:
701 int *iarg = arg;
703 dprintk(1, KERN_DEBUG "%s: decoder set output\n",
704 I2C_NAME(client));
706 /* not much choice of outputs */
707 if (*iarg != 0) {
708 return -EINVAL;
711 break;
713 case DECODER_ENABLE_OUTPUT:
715 int *iarg = arg;
716 int enable = (*iarg != 0);
718 dprintk(1, KERN_DEBUG "%s: decoder %s output\n",
719 I2C_NAME(client), enable ? "enable" : "disable");
721 decoder->playback = !enable;
723 if (decoder->enable != enable) {
724 decoder->enable = enable;
726 /* RJ: If output should be disabled (for
727 * playing videos), we also need a open PLL.
728 * The input is set to 0 (where no input
729 * source is connected), although this
730 * is not necessary.
732 * If output should be enabled, we have to
733 * reverse the above.
736 if (decoder->enable) {
737 decoder->reg[REG_ADDR(0x08)] = 0xb8;
738 decoder->reg[REG_ADDR(0x12)] = 0xc9;
739 decoder->reg[REG_ADDR(0x13)] = 0x80;
740 decoder->reg[REG_ADDR(0x87)] = 0x01;
741 } else {
742 decoder->reg[REG_ADDR(0x08)] = 0x7c;
743 decoder->reg[REG_ADDR(0x12)] = 0x00;
744 decoder->reg[REG_ADDR(0x13)] = 0x00;
745 decoder->reg[REG_ADDR(0x87)] = 0x00;
748 saa7114_write_block(client,
749 decoder->reg + (0x12 << 1),
750 2 << 1);
751 saa7114_write(client, 0x08,
752 decoder->reg[REG_ADDR(0x08)]);
753 saa7114_write(client, 0x87,
754 decoder->reg[REG_ADDR(0x87)]);
755 saa7114_write(client, 0x88, 0xd8); // sw reset scaler
756 saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
757 saa7114_write(client, 0x80, 0x36);
761 break;
763 case DECODER_SET_PICTURE:
765 struct video_picture *pic = arg;
767 dprintk(1,
768 KERN_DEBUG
769 "%s: decoder set picture bright=%d contrast=%d saturation=%d hue=%d\n",
770 I2C_NAME(client), pic->brightness, pic->contrast,
771 pic->colour, pic->hue);
773 if (decoder->bright != pic->brightness) {
774 /* We want 0 to 255 we get 0-65535 */
775 decoder->bright = pic->brightness;
776 saa7114_write(client, 0x0a, decoder->bright >> 8);
778 if (decoder->contrast != pic->contrast) {
779 /* We want 0 to 127 we get 0-65535 */
780 decoder->contrast = pic->contrast;
781 saa7114_write(client, 0x0b,
782 decoder->contrast >> 9);
784 if (decoder->sat != pic->colour) {
785 /* We want 0 to 127 we get 0-65535 */
786 decoder->sat = pic->colour;
787 saa7114_write(client, 0x0c, decoder->sat >> 9);
789 if (decoder->hue != pic->hue) {
790 /* We want -128 to 127 we get 0-65535 */
791 decoder->hue = pic->hue;
792 saa7114_write(client, 0x0d,
793 (decoder->hue - 32768) >> 8);
796 break;
798 default:
799 return -EINVAL;
802 return 0;
805 /* ----------------------------------------------------------------------- */
808 * Generic i2c probe
809 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
811 static unsigned short normal_i2c[] =
812 { I2C_SAA7114 >> 1, I2C_SAA7114A >> 1, I2C_CLIENT_END };
814 static unsigned short ignore = I2C_CLIENT_END;
816 static struct i2c_client_address_data addr_data = {
817 .normal_i2c = normal_i2c,
818 .probe = &ignore,
819 .ignore = &ignore,
822 static struct i2c_driver i2c_driver_saa7114;
824 static int
825 saa7114_detect_client (struct i2c_adapter *adapter,
826 int address,
827 int kind)
829 int i, err[30];
830 short int hoff = SAA_7114_NTSC_HOFFSET;
831 short int voff = SAA_7114_NTSC_VOFFSET;
832 short int w = SAA_7114_NTSC_WIDTH;
833 short int h = SAA_7114_NTSC_HEIGHT;
834 struct i2c_client *client;
835 struct saa7114 *decoder;
837 dprintk(1,
838 KERN_INFO
839 "saa7114.c: detecting saa7114 client on address 0x%x\n",
840 address << 1);
842 /* Check if the adapter supports the needed features */
843 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
844 return 0;
846 client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
847 if (client == 0)
848 return -ENOMEM;
849 client->addr = address;
850 client->adapter = adapter;
851 client->driver = &i2c_driver_saa7114;
852 strlcpy(I2C_NAME(client), "saa7114", sizeof(I2C_NAME(client)));
854 decoder = kzalloc(sizeof(struct saa7114), GFP_KERNEL);
855 if (decoder == NULL) {
856 kfree(client);
857 return -ENOMEM;
859 decoder->norm = VIDEO_MODE_NTSC;
860 decoder->input = -1;
861 decoder->enable = 1;
862 decoder->bright = 32768;
863 decoder->contrast = 32768;
864 decoder->hue = 32768;
865 decoder->sat = 32768;
866 decoder->playback = 0; // initially capture mode useda
867 i2c_set_clientdata(client, decoder);
869 memcpy(decoder->reg, init, sizeof(init));
871 decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff); // hoffset low
872 decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f; // hoffset high
873 decoder->reg[REG_ADDR(0x96)] = LOBYTE(w); // width low
874 decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f; // width high
875 decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff); // voffset low
876 decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f; // voffset high
877 decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2); // height low
878 decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f; // height high
879 decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w); // out width low
880 decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f; // out width high
881 decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h); // out height low
882 decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f; // out height high
884 decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff); // hoffset low
885 decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f; // hoffset high
886 decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w); // width low
887 decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f; // width high
888 decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff); // voffset low
889 decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f; // voffset high
890 decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2); // height low
891 decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f; // height high
892 decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w); // out width low
893 decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f; // out width high
894 decoder->reg[REG_ADDR(0xce)] = LOBYTE(h); // out height low
895 decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f; // out height high
897 decoder->reg[REG_ADDR(0xb8)] =
898 LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
899 decoder->reg[REG_ADDR(0xb9)] =
900 HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
901 decoder->reg[REG_ADDR(0xba)] =
902 LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
903 decoder->reg[REG_ADDR(0xbb)] =
904 HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
906 decoder->reg[REG_ADDR(0xbc)] =
907 LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
908 decoder->reg[REG_ADDR(0xbd)] =
909 HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
910 decoder->reg[REG_ADDR(0xbe)] =
911 LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
912 decoder->reg[REG_ADDR(0xbf)] =
913 HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
915 decoder->reg[REG_ADDR(0xe8)] =
916 LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
917 decoder->reg[REG_ADDR(0xe9)] =
918 HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
919 decoder->reg[REG_ADDR(0xea)] =
920 LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
921 decoder->reg[REG_ADDR(0xeb)] =
922 HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
924 decoder->reg[REG_ADDR(0xec)] =
925 LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
926 decoder->reg[REG_ADDR(0xed)] =
927 HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
928 decoder->reg[REG_ADDR(0xee)] =
929 LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
930 decoder->reg[REG_ADDR(0xef)] =
931 HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
934 decoder->reg[REG_ADDR(0x13)] = 0x80; // RTC0 on
935 decoder->reg[REG_ADDR(0x87)] = 0x01; // I-Port
936 decoder->reg[REG_ADDR(0x12)] = 0xc9; // RTS0
938 decoder->reg[REG_ADDR(0x02)] = 0xc0; // set composite1 input, aveasy
939 decoder->reg[REG_ADDR(0x09)] = 0x00; // chrominance trap
940 decoder->reg[REG_ADDR(0x0e)] |= 1; // combfilter on
943 dprintk(1, KERN_DEBUG "%s_attach: starting decoder init\n",
944 I2C_NAME(client));
946 err[0] =
947 saa7114_write_block(client, decoder->reg + (0x20 << 1),
948 0x10 << 1);
949 err[1] =
950 saa7114_write_block(client, decoder->reg + (0x30 << 1),
951 0x10 << 1);
952 err[2] =
953 saa7114_write_block(client, decoder->reg + (0x63 << 1),
954 (0x7f + 1 - 0x63) << 1);
955 err[3] =
956 saa7114_write_block(client, decoder->reg + (0x89 << 1),
957 6 << 1);
958 err[4] =
959 saa7114_write_block(client, decoder->reg + (0xb8 << 1),
960 8 << 1);
961 err[5] =
962 saa7114_write_block(client, decoder->reg + (0xe8 << 1),
963 8 << 1);
966 for (i = 0; i <= 5; i++) {
967 if (err[i] < 0) {
968 dprintk(1,
969 KERN_ERR
970 "%s_attach: init error %d at stage %d, leaving attach.\n",
971 I2C_NAME(client), i, err[i]);
972 kfree(decoder);
973 kfree(client);
974 return 0;
978 for (i = 6; i < 8; i++) {
979 dprintk(1,
980 KERN_DEBUG
981 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
982 I2C_NAME(client), i, saa7114_read(client, i),
983 decoder->reg[REG_ADDR(i)]);
986 dprintk(1,
987 KERN_DEBUG
988 "%s_attach: performing decoder reset sequence\n",
989 I2C_NAME(client));
991 err[6] = saa7114_write(client, 0x80, 0x06); // i-port and scaler backend clock selection, task A&B off
992 err[7] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler
993 err[8] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
995 for (i = 6; i <= 8; i++) {
996 if (err[i] < 0) {
997 dprintk(1,
998 KERN_ERR
999 "%s_attach: init error %d at stage %d, leaving attach.\n",
1000 I2C_NAME(client), i, err[i]);
1001 kfree(decoder);
1002 kfree(client);
1003 return 0;
1007 dprintk(1, KERN_INFO "%s_attach: performing the rest of init\n",
1008 I2C_NAME(client));
1011 err[9] = saa7114_write(client, 0x01, decoder->reg[REG_ADDR(0x01)]);
1012 err[10] = saa7114_write_block(client, decoder->reg + (0x03 << 1), (0x1e + 1 - 0x03) << 1); // big seq
1013 err[11] = saa7114_write_block(client, decoder->reg + (0x40 << 1), (0x5f + 1 - 0x40) << 1); // slicer
1014 err[12] = saa7114_write_block(client, decoder->reg + (0x81 << 1), 2 << 1); // ?
1015 err[13] = saa7114_write_block(client, decoder->reg + (0x83 << 1), 5 << 1); // ?
1016 err[14] = saa7114_write_block(client, decoder->reg + (0x90 << 1), 4 << 1); // Task A
1017 err[15] =
1018 saa7114_write_block(client, decoder->reg + (0x94 << 1),
1019 12 << 1);
1020 err[16] =
1021 saa7114_write_block(client, decoder->reg + (0xa0 << 1),
1022 8 << 1);
1023 err[17] =
1024 saa7114_write_block(client, decoder->reg + (0xa8 << 1),
1025 8 << 1);
1026 err[18] =
1027 saa7114_write_block(client, decoder->reg + (0xb0 << 1),
1028 8 << 1);
1029 err[19] = saa7114_write_block(client, decoder->reg + (0xc0 << 1), 4 << 1); // Task B
1030 err[15] =
1031 saa7114_write_block(client, decoder->reg + (0xc4 << 1),
1032 12 << 1);
1033 err[16] =
1034 saa7114_write_block(client, decoder->reg + (0xd0 << 1),
1035 8 << 1);
1036 err[17] =
1037 saa7114_write_block(client, decoder->reg + (0xd8 << 1),
1038 8 << 1);
1039 err[18] =
1040 saa7114_write_block(client, decoder->reg + (0xe0 << 1),
1041 8 << 1);
1043 for (i = 9; i <= 18; i++) {
1044 if (err[i] < 0) {
1045 dprintk(1,
1046 KERN_ERR
1047 "%s_attach: init error %d at stage %d, leaving attach.\n",
1048 I2C_NAME(client), i, err[i]);
1049 kfree(decoder);
1050 kfree(client);
1051 return 0;
1056 for (i = 6; i < 8; i++) {
1057 dprintk(1,
1058 KERN_DEBUG
1059 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
1060 I2C_NAME(client), i, saa7114_read(client, i),
1061 decoder->reg[REG_ADDR(i)]);
1065 for (i = 0x11; i <= 0x13; i++) {
1066 dprintk(1,
1067 KERN_DEBUG
1068 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
1069 I2C_NAME(client), i, saa7114_read(client, i),
1070 decoder->reg[REG_ADDR(i)]);
1074 dprintk(1, KERN_DEBUG "%s_attach: setting video input\n",
1075 I2C_NAME(client));
1077 err[19] =
1078 saa7114_write(client, 0x02, decoder->reg[REG_ADDR(0x02)]);
1079 err[20] =
1080 saa7114_write(client, 0x09, decoder->reg[REG_ADDR(0x09)]);
1081 err[21] =
1082 saa7114_write(client, 0x0e, decoder->reg[REG_ADDR(0x0e)]);
1084 for (i = 19; i <= 21; i++) {
1085 if (err[i] < 0) {
1086 dprintk(1,
1087 KERN_ERR
1088 "%s_attach: init error %d at stage %d, leaving attach.\n",
1089 I2C_NAME(client), i, err[i]);
1090 kfree(decoder);
1091 kfree(client);
1092 return 0;
1096 dprintk(1,
1097 KERN_DEBUG
1098 "%s_attach: performing decoder reset sequence\n",
1099 I2C_NAME(client));
1101 err[22] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler
1102 err[23] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
1103 err[24] = saa7114_write(client, 0x80, 0x36); // i-port and scaler backend clock selection, task A&B off
1106 for (i = 22; i <= 24; i++) {
1107 if (err[i] < 0) {
1108 dprintk(1,
1109 KERN_ERR
1110 "%s_attach: init error %d at stage %d, leaving attach.\n",
1111 I2C_NAME(client), i, err[i]);
1112 kfree(decoder);
1113 kfree(client);
1114 return 0;
1118 err[25] = saa7114_write(client, 0x06, init[REG_ADDR(0x06)]);
1119 err[26] = saa7114_write(client, 0x07, init[REG_ADDR(0x07)]);
1120 err[27] = saa7114_write(client, 0x10, init[REG_ADDR(0x10)]);
1122 dprintk(1,
1123 KERN_INFO
1124 "%s_attach: chip version %x, decoder status 0x%02x\n",
1125 I2C_NAME(client), saa7114_read(client, 0x00) >> 4,
1126 saa7114_read(client, 0x1f));
1127 dprintk(1,
1128 KERN_DEBUG
1129 "%s_attach: power save control: 0x%02x, scaler status: 0x%02x\n",
1130 I2C_NAME(client), saa7114_read(client, 0x88),
1131 saa7114_read(client, 0x8f));
1134 for (i = 0x94; i < 0x96; i++) {
1135 dprintk(1,
1136 KERN_DEBUG
1137 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
1138 I2C_NAME(client), i, saa7114_read(client, i),
1139 decoder->reg[REG_ADDR(i)]);
1142 i = i2c_attach_client(client);
1143 if (i) {
1144 kfree(client);
1145 kfree(decoder);
1146 return i;
1149 //i = saa7114_write_block(client, init, sizeof(init));
1150 i = 0;
1151 if (i < 0) {
1152 dprintk(1, KERN_ERR "%s_attach error: init status %d\n",
1153 I2C_NAME(client), i);
1154 } else {
1155 dprintk(1,
1156 KERN_INFO
1157 "%s_attach: chip version %x at address 0x%x\n",
1158 I2C_NAME(client), saa7114_read(client, 0x00) >> 4,
1159 client->addr << 1);
1162 return 0;
1165 static int
1166 saa7114_attach_adapter (struct i2c_adapter *adapter)
1168 dprintk(1,
1169 KERN_INFO
1170 "saa7114.c: starting probe for adapter %s (0x%x)\n",
1171 I2C_NAME(adapter), adapter->id);
1172 return i2c_probe(adapter, &addr_data, &saa7114_detect_client);
1175 static int
1176 saa7114_detach_client (struct i2c_client *client)
1178 struct saa7114 *decoder = i2c_get_clientdata(client);
1179 int err;
1181 err = i2c_detach_client(client);
1182 if (err) {
1183 return err;
1186 kfree(decoder);
1187 kfree(client);
1189 return 0;
1192 /* ----------------------------------------------------------------------- */
1194 static struct i2c_driver i2c_driver_saa7114 = {
1195 .driver = {
1196 .name = "saa7114",
1199 .id = I2C_DRIVERID_SAA7114,
1201 .attach_adapter = saa7114_attach_adapter,
1202 .detach_client = saa7114_detach_client,
1203 .command = saa7114_command,
1206 static int __init
1207 saa7114_init (void)
1209 return i2c_add_driver(&i2c_driver_saa7114);
1212 static void __exit
1213 saa7114_exit (void)
1215 i2c_del_driver(&i2c_driver_saa7114);
1218 module_init(saa7114_init);
1219 module_exit(saa7114_exit);