Revert "[PATCH] paravirt: Add startup infrastructure for paravirtualization"
[pv_ops_mirror.git] / drivers / media / video / saa7114.c
blob87c3144ec7fc85e1e0aeab3cdc1fc28ac32c9f8c
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/signal.h>
43 #include <asm/io.h>
44 #include <asm/pgtable.h>
45 #include <asm/page.h>
46 #include <linux/types.h>
48 #include <linux/videodev.h>
49 #include <asm/uaccess.h>
51 MODULE_DESCRIPTION("Philips SAA7114H video decoder driver");
52 MODULE_AUTHOR("Maxim Yevtyushkin");
53 MODULE_LICENSE("GPL");
55 #include <linux/i2c.h>
57 #define I2C_NAME(x) (x)->name
59 #include <linux/video_decoder.h>
61 static int debug = 0;
62 module_param(debug, int, 0);
63 MODULE_PARM_DESC(debug, "Debug level (0-1)");
65 #define dprintk(num, format, args...) \
66 do { \
67 if (debug >= num) \
68 printk(format, ##args); \
69 } while (0)
71 /* ----------------------------------------------------------------------- */
73 struct saa7114 {
74 unsigned char reg[0xf0 * 2];
76 int norm;
77 int input;
78 int enable;
79 int bright;
80 int contrast;
81 int hue;
82 int sat;
83 int playback;
86 #define I2C_SAA7114 0x42
87 #define I2C_SAA7114A 0x40
89 #define I2C_DELAY 10
92 //#define SAA_7114_NTSC_HSYNC_START (-3)
93 //#define SAA_7114_NTSC_HSYNC_STOP (-18)
95 #define SAA_7114_NTSC_HSYNC_START (-17)
96 #define SAA_7114_NTSC_HSYNC_STOP (-32)
98 //#define SAA_7114_NTSC_HOFFSET (5)
99 #define SAA_7114_NTSC_HOFFSET (6)
100 #define SAA_7114_NTSC_VOFFSET (10)
101 #define SAA_7114_NTSC_WIDTH (720)
102 #define SAA_7114_NTSC_HEIGHT (250)
104 #define SAA_7114_SECAM_HSYNC_START (-17)
105 #define SAA_7114_SECAM_HSYNC_STOP (-32)
107 #define SAA_7114_SECAM_HOFFSET (2)
108 #define SAA_7114_SECAM_VOFFSET (10)
109 #define SAA_7114_SECAM_WIDTH (720)
110 #define SAA_7114_SECAM_HEIGHT (300)
112 #define SAA_7114_PAL_HSYNC_START (-17)
113 #define SAA_7114_PAL_HSYNC_STOP (-32)
115 #define SAA_7114_PAL_HOFFSET (2)
116 #define SAA_7114_PAL_VOFFSET (10)
117 #define SAA_7114_PAL_WIDTH (720)
118 #define SAA_7114_PAL_HEIGHT (300)
122 #define SAA_7114_VERTICAL_CHROMA_OFFSET 0 //0x50504040
123 #define SAA_7114_VERTICAL_LUMA_OFFSET 0
125 #define REG_ADDR(x) (((x) << 1) + 1)
126 #define LOBYTE(x) ((unsigned char)((x) & 0xff))
127 #define HIBYTE(x) ((unsigned char)(((x) >> 8) & 0xff))
128 #define LOWORD(x) ((unsigned short int)((x) & 0xffff))
129 #define HIWORD(x) ((unsigned short int)(((x) >> 16) & 0xffff))
132 /* ----------------------------------------------------------------------- */
134 static inline int
135 saa7114_write (struct i2c_client *client,
136 u8 reg,
137 u8 value)
139 return i2c_smbus_write_byte_data(client, reg, value);
142 static int
143 saa7114_write_block (struct i2c_client *client,
144 const u8 *data,
145 unsigned int len)
147 int ret = -1;
148 u8 reg;
150 /* the saa7114 has an autoincrement function, use it if
151 * the adapter understands raw I2C */
152 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
153 /* do raw I2C, not smbus compatible */
154 u8 block_data[32];
155 int block_len;
157 while (len >= 2) {
158 block_len = 0;
159 block_data[block_len++] = reg = data[0];
160 do {
161 block_data[block_len++] = data[1];
162 reg++;
163 len -= 2;
164 data += 2;
165 } while (len >= 2 && data[0] == reg &&
166 block_len < 32);
167 if ((ret = i2c_master_send(client, block_data,
168 block_len)) < 0)
169 break;
171 } else {
172 /* do some slow I2C emulation kind of thing */
173 while (len >= 2) {
174 reg = *data++;
175 if ((ret = saa7114_write(client, reg,
176 *data++)) < 0)
177 break;
178 len -= 2;
182 return ret;
185 static inline int
186 saa7114_read (struct i2c_client *client,
187 u8 reg)
189 return i2c_smbus_read_byte_data(client, reg);
192 /* ----------------------------------------------------------------------- */
194 // initially set NTSC, composite
197 static const unsigned char init[] = {
198 0x00, 0x00, /* 00 - ID byte , chip version,
199 * read only */
200 0x01, 0x08, /* 01 - X,X,X,X, IDEL3 to IDEL0 -
201 * horizontal increment delay,
202 * recommended position */
203 0x02, 0x00, /* 02 - FUSE=3, GUDL=2, MODE=0 ;
204 * input control */
205 0x03, 0x10, /* 03 - HLNRS=0, VBSL=1, WPOFF=0,
206 * HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
207 0x04, 0x90, /* 04 - GAI1=256 */
208 0x05, 0x90, /* 05 - GAI2=256 */
209 0x06, SAA_7114_NTSC_HSYNC_START, /* 06 - HSB: hsync start,
210 * depends on the video standard */
211 0x07, SAA_7114_NTSC_HSYNC_STOP, /* 07 - HSS: hsync stop, depends
212 *on the video standard */
213 0x08, 0xb8, /* 08 - AUFD=1, FSEL=1, EXFIL=0, VTRC=1,
214 * HPLL: free running in playback, locked
215 * in capture, VNOI=0 */
216 0x09, 0x80, /* 09 - BYPS=0, PREF=0, BPSS=0, VBLB=0,
217 * UPTCV=0, APER=1; depends from input */
218 0x0a, 0x80, /* 0a - BRIG=128 */
219 0x0b, 0x44, /* 0b - CONT=1.109 */
220 0x0c, 0x40, /* 0c - SATN=1.0 */
221 0x0d, 0x00, /* 0d - HUE=0 */
222 0x0e, 0x84, /* 0e - CDTO, CSTD2 to 0, DCVF, FCTC,
223 * CCOMB; depends from video standard */
224 0x0f, 0x24, /* 0f - ACGC,CGAIN6 to CGAIN0; depends
225 * from video standard */
226 0x10, 0x03, /* 10 - OFFU1 to 0, OFFV1 to 0, CHBW,
227 * LCBW2 to 0 */
228 0x11, 0x59, /* 11 - COLO, RTP1, HEDL1 to 0, RTP0,
229 * YDEL2 to 0 */
230 0x12, 0xc9, /* 12 - RT signal control RTSE13 to 10
231 * and 03 to 00 */
232 0x13, 0x80, /* 13 - RT/X port output control */
233 0x14, 0x00, /* 14 - analog, ADC, compatibility control */
234 0x15, 0x00, /* 15 - VGATE start FID change */
235 0x16, 0xfe, /* 16 - VGATE stop */
236 0x17, 0x00, /* 17 - Misc., VGATE MSBs */
237 0x18, 0x40, /* RAWG */
238 0x19, 0x80, /* RAWO */
239 0x1a, 0x00,
240 0x1b, 0x00,
241 0x1c, 0x00,
242 0x1d, 0x00,
243 0x1e, 0x00,
244 0x1f, 0x00, /* status byte, read only */
245 0x20, 0x00, /* video decoder reserved part */
246 0x21, 0x00,
247 0x22, 0x00,
248 0x23, 0x00,
249 0x24, 0x00,
250 0x25, 0x00,
251 0x26, 0x00,
252 0x27, 0x00,
253 0x28, 0x00,
254 0x29, 0x00,
255 0x2a, 0x00,
256 0x2b, 0x00,
257 0x2c, 0x00,
258 0x2d, 0x00,
259 0x2e, 0x00,
260 0x2f, 0x00,
261 0x30, 0xbc, /* audio clock generator */
262 0x31, 0xdf,
263 0x32, 0x02,
264 0x33, 0x00,
265 0x34, 0xcd,
266 0x35, 0xcc,
267 0x36, 0x3a,
268 0x37, 0x00,
269 0x38, 0x03,
270 0x39, 0x10,
271 0x3a, 0x00,
272 0x3b, 0x00,
273 0x3c, 0x00,
274 0x3d, 0x00,
275 0x3e, 0x00,
276 0x3f, 0x00,
277 0x40, 0x00, /* VBI data slicer */
278 0x41, 0xff,
279 0x42, 0xff,
280 0x43, 0xff,
281 0x44, 0xff,
282 0x45, 0xff,
283 0x46, 0xff,
284 0x47, 0xff,
285 0x48, 0xff,
286 0x49, 0xff,
287 0x4a, 0xff,
288 0x4b, 0xff,
289 0x4c, 0xff,
290 0x4d, 0xff,
291 0x4e, 0xff,
292 0x4f, 0xff,
293 0x50, 0xff,
294 0x51, 0xff,
295 0x52, 0xff,
296 0x53, 0xff,
297 0x54, 0xff,
298 0x55, 0xff,
299 0x56, 0xff,
300 0x57, 0xff,
301 0x58, 0x40, // framing code
302 0x59, 0x47, // horizontal offset
303 0x5a, 0x06, // vertical offset
304 0x5b, 0x83, // field offset
305 0x5c, 0x00, // reserved
306 0x5d, 0x3e, // header and data
307 0x5e, 0x00, // sliced data
308 0x5f, 0x00, // reserved
309 0x60, 0x00, /* video decoder reserved part */
310 0x61, 0x00,
311 0x62, 0x00,
312 0x63, 0x00,
313 0x64, 0x00,
314 0x65, 0x00,
315 0x66, 0x00,
316 0x67, 0x00,
317 0x68, 0x00,
318 0x69, 0x00,
319 0x6a, 0x00,
320 0x6b, 0x00,
321 0x6c, 0x00,
322 0x6d, 0x00,
323 0x6e, 0x00,
324 0x6f, 0x00,
325 0x70, 0x00, /* video decoder reserved part */
326 0x71, 0x00,
327 0x72, 0x00,
328 0x73, 0x00,
329 0x74, 0x00,
330 0x75, 0x00,
331 0x76, 0x00,
332 0x77, 0x00,
333 0x78, 0x00,
334 0x79, 0x00,
335 0x7a, 0x00,
336 0x7b, 0x00,
337 0x7c, 0x00,
338 0x7d, 0x00,
339 0x7e, 0x00,
340 0x7f, 0x00,
341 0x80, 0x00, /* X-port, I-port and scaler */
342 0x81, 0x00,
343 0x82, 0x00,
344 0x83, 0x00,
345 0x84, 0xc5,
346 0x85, 0x0d, // hsync and vsync ?
347 0x86, 0x40,
348 0x87, 0x01,
349 0x88, 0x00,
350 0x89, 0x00,
351 0x8a, 0x00,
352 0x8b, 0x00,
353 0x8c, 0x00,
354 0x8d, 0x00,
355 0x8e, 0x00,
356 0x8f, 0x00,
357 0x90, 0x03, /* Task A definition */
358 0x91, 0x08,
359 0x92, 0x00,
360 0x93, 0x40,
361 0x94, 0x00, // window settings
362 0x95, 0x00,
363 0x96, 0x00,
364 0x97, 0x00,
365 0x98, 0x00,
366 0x99, 0x00,
367 0x9a, 0x00,
368 0x9b, 0x00,
369 0x9c, 0x00,
370 0x9d, 0x00,
371 0x9e, 0x00,
372 0x9f, 0x00,
373 0xa0, 0x01, /* horizontal integer prescaling ratio */
374 0xa1, 0x00, /* horizontal prescaler accumulation
375 * sequence length */
376 0xa2, 0x00, /* UV FIR filter, Y FIR filter, prescaler
377 * DC gain */
378 0xa3, 0x00,
379 0xa4, 0x80, // luminance brightness
380 0xa5, 0x40, // luminance gain
381 0xa6, 0x40, // chrominance saturation
382 0xa7, 0x00,
383 0xa8, 0x00, // horizontal luminance scaling increment
384 0xa9, 0x04,
385 0xaa, 0x00, // horizontal luminance phase offset
386 0xab, 0x00,
387 0xac, 0x00, // horizontal chrominance scaling increment
388 0xad, 0x02,
389 0xae, 0x00, // horizontal chrominance phase offset
390 0xaf, 0x00,
391 0xb0, 0x00, // vertical luminance scaling increment
392 0xb1, 0x04,
393 0xb2, 0x00, // vertical chrominance scaling increment
394 0xb3, 0x04,
395 0xb4, 0x00,
396 0xb5, 0x00,
397 0xb6, 0x00,
398 0xb7, 0x00,
399 0xb8, 0x00,
400 0xb9, 0x00,
401 0xba, 0x00,
402 0xbb, 0x00,
403 0xbc, 0x00,
404 0xbd, 0x00,
405 0xbe, 0x00,
406 0xbf, 0x00,
407 0xc0, 0x02, // Task B definition
408 0xc1, 0x08,
409 0xc2, 0x00,
410 0xc3, 0x40,
411 0xc4, 0x00, // window settings
412 0xc5, 0x00,
413 0xc6, 0x00,
414 0xc7, 0x00,
415 0xc8, 0x00,
416 0xc9, 0x00,
417 0xca, 0x00,
418 0xcb, 0x00,
419 0xcc, 0x00,
420 0xcd, 0x00,
421 0xce, 0x00,
422 0xcf, 0x00,
423 0xd0, 0x01, // horizontal integer prescaling ratio
424 0xd1, 0x00, // horizontal prescaler accumulation sequence length
425 0xd2, 0x00, // UV FIR filter, Y FIR filter, prescaler DC gain
426 0xd3, 0x00,
427 0xd4, 0x80, // luminance brightness
428 0xd5, 0x40, // luminance gain
429 0xd6, 0x40, // chrominance saturation
430 0xd7, 0x00,
431 0xd8, 0x00, // horizontal luminance scaling increment
432 0xd9, 0x04,
433 0xda, 0x00, // horizontal luminance phase offset
434 0xdb, 0x00,
435 0xdc, 0x00, // horizontal chrominance scaling increment
436 0xdd, 0x02,
437 0xde, 0x00, // horizontal chrominance phase offset
438 0xdf, 0x00,
439 0xe0, 0x00, // vertical luminance scaling increment
440 0xe1, 0x04,
441 0xe2, 0x00, // vertical chrominance scaling increment
442 0xe3, 0x04,
443 0xe4, 0x00,
444 0xe5, 0x00,
445 0xe6, 0x00,
446 0xe7, 0x00,
447 0xe8, 0x00,
448 0xe9, 0x00,
449 0xea, 0x00,
450 0xeb, 0x00,
451 0xec, 0x00,
452 0xed, 0x00,
453 0xee, 0x00,
454 0xef, 0x00
457 static int
458 saa7114_command (struct i2c_client *client,
459 unsigned int cmd,
460 void *arg)
462 struct saa7114 *decoder = i2c_get_clientdata(client);
464 switch (cmd) {
466 case 0:
467 //dprintk(1, KERN_INFO "%s: writing init\n", I2C_NAME(client));
468 //saa7114_write_block(client, init, sizeof(init));
469 break;
471 case DECODER_DUMP:
473 int i;
475 dprintk(1, KERN_INFO "%s: decoder dump\n", I2C_NAME(client));
477 for (i = 0; i < 32; i += 16) {
478 int j;
480 printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i);
481 for (j = 0; j < 16; ++j) {
482 printk(" %02x",
483 saa7114_read(client, i + j));
485 printk("\n");
488 break;
490 case DECODER_GET_CAPABILITIES:
492 struct video_decoder_capability *cap = arg;
494 dprintk(1, KERN_DEBUG "%s: decoder get capabilities\n",
495 I2C_NAME(client));
497 cap->flags = VIDEO_DECODER_PAL |
498 VIDEO_DECODER_NTSC |
499 VIDEO_DECODER_AUTO |
500 VIDEO_DECODER_CCIR;
501 cap->inputs = 8;
502 cap->outputs = 1;
504 break;
506 case DECODER_GET_STATUS:
508 int *iarg = arg;
509 int status;
510 int res;
512 status = saa7114_read(client, 0x1f);
514 dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client),
515 status);
516 res = 0;
517 if ((status & (1 << 6)) == 0) {
518 res |= DECODER_STATUS_GOOD;
520 switch (decoder->norm) {
521 case VIDEO_MODE_NTSC:
522 res |= DECODER_STATUS_NTSC;
523 break;
524 case VIDEO_MODE_PAL:
525 res |= DECODER_STATUS_PAL;
526 break;
527 case VIDEO_MODE_SECAM:
528 res |= DECODER_STATUS_SECAM;
529 break;
530 default:
531 case VIDEO_MODE_AUTO:
532 if ((status & (1 << 5)) != 0) {
533 res |= DECODER_STATUS_NTSC;
534 } else {
535 res |= DECODER_STATUS_PAL;
537 break;
539 if ((status & (1 << 0)) != 0) {
540 res |= DECODER_STATUS_COLOR;
542 *iarg = res;
544 break;
546 case DECODER_SET_NORM:
548 int *iarg = arg;
550 short int hoff = 0, voff = 0, w = 0, h = 0;
552 dprintk(1, KERN_DEBUG "%s: decoder set norm ",
553 I2C_NAME(client));
554 switch (*iarg) {
556 case VIDEO_MODE_NTSC:
557 dprintk(1, "NTSC\n");
558 decoder->reg[REG_ADDR(0x06)] =
559 SAA_7114_NTSC_HSYNC_START;
560 decoder->reg[REG_ADDR(0x07)] =
561 SAA_7114_NTSC_HSYNC_STOP;
563 decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8; // PLL free when playback, PLL close when capture
565 decoder->reg[REG_ADDR(0x0e)] = 0x85;
566 decoder->reg[REG_ADDR(0x0f)] = 0x24;
568 hoff = SAA_7114_NTSC_HOFFSET;
569 voff = SAA_7114_NTSC_VOFFSET;
570 w = SAA_7114_NTSC_WIDTH;
571 h = SAA_7114_NTSC_HEIGHT;
573 break;
575 case VIDEO_MODE_PAL:
576 dprintk(1, "PAL\n");
577 decoder->reg[REG_ADDR(0x06)] =
578 SAA_7114_PAL_HSYNC_START;
579 decoder->reg[REG_ADDR(0x07)] =
580 SAA_7114_PAL_HSYNC_STOP;
582 decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8; // PLL free when playback, PLL close when capture
584 decoder->reg[REG_ADDR(0x0e)] = 0x81;
585 decoder->reg[REG_ADDR(0x0f)] = 0x24;
587 hoff = SAA_7114_PAL_HOFFSET;
588 voff = SAA_7114_PAL_VOFFSET;
589 w = SAA_7114_PAL_WIDTH;
590 h = SAA_7114_PAL_HEIGHT;
592 break;
594 default:
595 dprintk(1, " Unknown video mode!!!\n");
596 return -EINVAL;
601 decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff); // hoffset low
602 decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f; // hoffset high
603 decoder->reg[REG_ADDR(0x96)] = LOBYTE(w); // width low
604 decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f; // width high
605 decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff); // voffset low
606 decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f; // voffset high
607 decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2); // height low
608 decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f; // height high
609 decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w); // out width low
610 decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f; // out width high
611 decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h); // out height low
612 decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f; // out height high
614 decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff); // hoffset low
615 decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f; // hoffset high
616 decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w); // width low
617 decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f; // width high
618 decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff); // voffset low
619 decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f; // voffset high
620 decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2); // height low
621 decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f; // height high
622 decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w); // out width low
623 decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f; // out width high
624 decoder->reg[REG_ADDR(0xce)] = LOBYTE(h); // out height low
625 decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f; // out height high
628 saa7114_write(client, 0x80, 0x06); // i-port and scaler back end clock selection, task A&B off
629 saa7114_write(client, 0x88, 0xd8); // sw reset scaler
630 saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
632 saa7114_write_block(client, decoder->reg + (0x06 << 1),
633 3 << 1);
634 saa7114_write_block(client, decoder->reg + (0x0e << 1),
635 2 << 1);
636 saa7114_write_block(client, decoder->reg + (0x5a << 1),
637 2 << 1);
639 saa7114_write_block(client, decoder->reg + (0x94 << 1),
640 (0x9f + 1 - 0x94) << 1);
641 saa7114_write_block(client, decoder->reg + (0xc4 << 1),
642 (0xcf + 1 - 0xc4) << 1);
644 saa7114_write(client, 0x88, 0xd8); // sw reset scaler
645 saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
646 saa7114_write(client, 0x80, 0x36); // i-port and scaler back end clock selection
648 decoder->norm = *iarg;
650 break;
652 case DECODER_SET_INPUT:
654 int *iarg = arg;
656 dprintk(1, KERN_DEBUG "%s: decoder set input (%d)\n",
657 I2C_NAME(client), *iarg);
658 if (*iarg < 0 || *iarg > 7) {
659 return -EINVAL;
662 if (decoder->input != *iarg) {
663 dprintk(1, KERN_DEBUG "%s: now setting %s input\n",
664 I2C_NAME(client),
665 *iarg >= 6 ? "S-Video" : "Composite");
666 decoder->input = *iarg;
668 /* select mode */
669 decoder->reg[REG_ADDR(0x02)] =
670 (decoder->
671 reg[REG_ADDR(0x02)] & 0xf0) | (decoder->
672 input <
673 6 ? 0x0 : 0x9);
674 saa7114_write(client, 0x02,
675 decoder->reg[REG_ADDR(0x02)]);
677 /* bypass chrominance trap for modes 6..9 */
678 decoder->reg[REG_ADDR(0x09)] =
679 (decoder->
680 reg[REG_ADDR(0x09)] & 0x7f) | (decoder->
681 input <
682 6 ? 0x0 :
683 0x80);
684 saa7114_write(client, 0x09,
685 decoder->reg[REG_ADDR(0x09)]);
687 decoder->reg[REG_ADDR(0x0e)] =
688 decoder->input <
689 6 ? decoder->
690 reg[REG_ADDR(0x0e)] | 1 : decoder->
691 reg[REG_ADDR(0x0e)] & ~1;
692 saa7114_write(client, 0x0e,
693 decoder->reg[REG_ADDR(0x0e)]);
696 break;
698 case DECODER_SET_OUTPUT:
700 int *iarg = arg;
702 dprintk(1, KERN_DEBUG "%s: decoder set output\n",
703 I2C_NAME(client));
705 /* not much choice of outputs */
706 if (*iarg != 0) {
707 return -EINVAL;
710 break;
712 case DECODER_ENABLE_OUTPUT:
714 int *iarg = arg;
715 int enable = (*iarg != 0);
717 dprintk(1, KERN_DEBUG "%s: decoder %s output\n",
718 I2C_NAME(client), enable ? "enable" : "disable");
720 decoder->playback = !enable;
722 if (decoder->enable != enable) {
723 decoder->enable = enable;
725 /* RJ: If output should be disabled (for
726 * playing videos), we also need a open PLL.
727 * The input is set to 0 (where no input
728 * source is connected), although this
729 * is not necessary.
731 * If output should be enabled, we have to
732 * reverse the above.
735 if (decoder->enable) {
736 decoder->reg[REG_ADDR(0x08)] = 0xb8;
737 decoder->reg[REG_ADDR(0x12)] = 0xc9;
738 decoder->reg[REG_ADDR(0x13)] = 0x80;
739 decoder->reg[REG_ADDR(0x87)] = 0x01;
740 } else {
741 decoder->reg[REG_ADDR(0x08)] = 0x7c;
742 decoder->reg[REG_ADDR(0x12)] = 0x00;
743 decoder->reg[REG_ADDR(0x13)] = 0x00;
744 decoder->reg[REG_ADDR(0x87)] = 0x00;
747 saa7114_write_block(client,
748 decoder->reg + (0x12 << 1),
749 2 << 1);
750 saa7114_write(client, 0x08,
751 decoder->reg[REG_ADDR(0x08)]);
752 saa7114_write(client, 0x87,
753 decoder->reg[REG_ADDR(0x87)]);
754 saa7114_write(client, 0x88, 0xd8); // sw reset scaler
755 saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
756 saa7114_write(client, 0x80, 0x36);
760 break;
762 case DECODER_SET_PICTURE:
764 struct video_picture *pic = arg;
766 dprintk(1,
767 KERN_DEBUG
768 "%s: decoder set picture bright=%d contrast=%d saturation=%d hue=%d\n",
769 I2C_NAME(client), pic->brightness, pic->contrast,
770 pic->colour, pic->hue);
772 if (decoder->bright != pic->brightness) {
773 /* We want 0 to 255 we get 0-65535 */
774 decoder->bright = pic->brightness;
775 saa7114_write(client, 0x0a, decoder->bright >> 8);
777 if (decoder->contrast != pic->contrast) {
778 /* We want 0 to 127 we get 0-65535 */
779 decoder->contrast = pic->contrast;
780 saa7114_write(client, 0x0b,
781 decoder->contrast >> 9);
783 if (decoder->sat != pic->colour) {
784 /* We want 0 to 127 we get 0-65535 */
785 decoder->sat = pic->colour;
786 saa7114_write(client, 0x0c, decoder->sat >> 9);
788 if (decoder->hue != pic->hue) {
789 /* We want -128 to 127 we get 0-65535 */
790 decoder->hue = pic->hue;
791 saa7114_write(client, 0x0d,
792 (decoder->hue - 32768) >> 8);
795 break;
797 default:
798 return -EINVAL;
801 return 0;
804 /* ----------------------------------------------------------------------- */
807 * Generic i2c probe
808 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
810 static unsigned short normal_i2c[] =
811 { I2C_SAA7114 >> 1, I2C_SAA7114A >> 1, I2C_CLIENT_END };
813 static unsigned short ignore = I2C_CLIENT_END;
815 static struct i2c_client_address_data addr_data = {
816 .normal_i2c = normal_i2c,
817 .probe = &ignore,
818 .ignore = &ignore,
821 static struct i2c_driver i2c_driver_saa7114;
823 static int
824 saa7114_detect_client (struct i2c_adapter *adapter,
825 int address,
826 int kind)
828 int i, err[30];
829 short int hoff = SAA_7114_NTSC_HOFFSET;
830 short int voff = SAA_7114_NTSC_VOFFSET;
831 short int w = SAA_7114_NTSC_WIDTH;
832 short int h = SAA_7114_NTSC_HEIGHT;
833 struct i2c_client *client;
834 struct saa7114 *decoder;
836 dprintk(1,
837 KERN_INFO
838 "saa7114.c: detecting saa7114 client on address 0x%x\n",
839 address << 1);
841 /* Check if the adapter supports the needed features */
842 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
843 return 0;
845 client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
846 if (client == 0)
847 return -ENOMEM;
848 client->addr = address;
849 client->adapter = adapter;
850 client->driver = &i2c_driver_saa7114;
851 strlcpy(I2C_NAME(client), "saa7114", sizeof(I2C_NAME(client)));
853 decoder = kzalloc(sizeof(struct saa7114), GFP_KERNEL);
854 if (decoder == NULL) {
855 kfree(client);
856 return -ENOMEM;
858 decoder->norm = VIDEO_MODE_NTSC;
859 decoder->input = -1;
860 decoder->enable = 1;
861 decoder->bright = 32768;
862 decoder->contrast = 32768;
863 decoder->hue = 32768;
864 decoder->sat = 32768;
865 decoder->playback = 0; // initially capture mode useda
866 i2c_set_clientdata(client, decoder);
868 memcpy(decoder->reg, init, sizeof(init));
870 decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff); // hoffset low
871 decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f; // hoffset high
872 decoder->reg[REG_ADDR(0x96)] = LOBYTE(w); // width low
873 decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f; // width high
874 decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff); // voffset low
875 decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f; // voffset high
876 decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2); // height low
877 decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f; // height high
878 decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w); // out width low
879 decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f; // out width high
880 decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h); // out height low
881 decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f; // out height high
883 decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff); // hoffset low
884 decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f; // hoffset high
885 decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w); // width low
886 decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f; // width high
887 decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff); // voffset low
888 decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f; // voffset high
889 decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2); // height low
890 decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f; // height high
891 decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w); // out width low
892 decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f; // out width high
893 decoder->reg[REG_ADDR(0xce)] = LOBYTE(h); // out height low
894 decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f; // out height high
896 decoder->reg[REG_ADDR(0xb8)] =
897 LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
898 decoder->reg[REG_ADDR(0xb9)] =
899 HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
900 decoder->reg[REG_ADDR(0xba)] =
901 LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
902 decoder->reg[REG_ADDR(0xbb)] =
903 HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
905 decoder->reg[REG_ADDR(0xbc)] =
906 LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
907 decoder->reg[REG_ADDR(0xbd)] =
908 HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
909 decoder->reg[REG_ADDR(0xbe)] =
910 LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
911 decoder->reg[REG_ADDR(0xbf)] =
912 HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
914 decoder->reg[REG_ADDR(0xe8)] =
915 LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
916 decoder->reg[REG_ADDR(0xe9)] =
917 HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
918 decoder->reg[REG_ADDR(0xea)] =
919 LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
920 decoder->reg[REG_ADDR(0xeb)] =
921 HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
923 decoder->reg[REG_ADDR(0xec)] =
924 LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
925 decoder->reg[REG_ADDR(0xed)] =
926 HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
927 decoder->reg[REG_ADDR(0xee)] =
928 LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
929 decoder->reg[REG_ADDR(0xef)] =
930 HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
933 decoder->reg[REG_ADDR(0x13)] = 0x80; // RTC0 on
934 decoder->reg[REG_ADDR(0x87)] = 0x01; // I-Port
935 decoder->reg[REG_ADDR(0x12)] = 0xc9; // RTS0
937 decoder->reg[REG_ADDR(0x02)] = 0xc0; // set composite1 input, aveasy
938 decoder->reg[REG_ADDR(0x09)] = 0x00; // chrominance trap
939 decoder->reg[REG_ADDR(0x0e)] |= 1; // combfilter on
942 dprintk(1, KERN_DEBUG "%s_attach: starting decoder init\n",
943 I2C_NAME(client));
945 err[0] =
946 saa7114_write_block(client, decoder->reg + (0x20 << 1),
947 0x10 << 1);
948 err[1] =
949 saa7114_write_block(client, decoder->reg + (0x30 << 1),
950 0x10 << 1);
951 err[2] =
952 saa7114_write_block(client, decoder->reg + (0x63 << 1),
953 (0x7f + 1 - 0x63) << 1);
954 err[3] =
955 saa7114_write_block(client, decoder->reg + (0x89 << 1),
956 6 << 1);
957 err[4] =
958 saa7114_write_block(client, decoder->reg + (0xb8 << 1),
959 8 << 1);
960 err[5] =
961 saa7114_write_block(client, decoder->reg + (0xe8 << 1),
962 8 << 1);
965 for (i = 0; i <= 5; i++) {
966 if (err[i] < 0) {
967 dprintk(1,
968 KERN_ERR
969 "%s_attach: init error %d at stage %d, leaving attach.\n",
970 I2C_NAME(client), i, err[i]);
971 kfree(decoder);
972 kfree(client);
973 return 0;
977 for (i = 6; i < 8; i++) {
978 dprintk(1,
979 KERN_DEBUG
980 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
981 I2C_NAME(client), i, saa7114_read(client, i),
982 decoder->reg[REG_ADDR(i)]);
985 dprintk(1,
986 KERN_DEBUG
987 "%s_attach: performing decoder reset sequence\n",
988 I2C_NAME(client));
990 err[6] = saa7114_write(client, 0x80, 0x06); // i-port and scaler backend clock selection, task A&B off
991 err[7] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler
992 err[8] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
994 for (i = 6; i <= 8; i++) {
995 if (err[i] < 0) {
996 dprintk(1,
997 KERN_ERR
998 "%s_attach: init error %d at stage %d, leaving attach.\n",
999 I2C_NAME(client), i, err[i]);
1000 kfree(decoder);
1001 kfree(client);
1002 return 0;
1006 dprintk(1, KERN_INFO "%s_attach: performing the rest of init\n",
1007 I2C_NAME(client));
1010 err[9] = saa7114_write(client, 0x01, decoder->reg[REG_ADDR(0x01)]);
1011 err[10] = saa7114_write_block(client, decoder->reg + (0x03 << 1), (0x1e + 1 - 0x03) << 1); // big seq
1012 err[11] = saa7114_write_block(client, decoder->reg + (0x40 << 1), (0x5f + 1 - 0x40) << 1); // slicer
1013 err[12] = saa7114_write_block(client, decoder->reg + (0x81 << 1), 2 << 1); // ?
1014 err[13] = saa7114_write_block(client, decoder->reg + (0x83 << 1), 5 << 1); // ?
1015 err[14] = saa7114_write_block(client, decoder->reg + (0x90 << 1), 4 << 1); // Task A
1016 err[15] =
1017 saa7114_write_block(client, decoder->reg + (0x94 << 1),
1018 12 << 1);
1019 err[16] =
1020 saa7114_write_block(client, decoder->reg + (0xa0 << 1),
1021 8 << 1);
1022 err[17] =
1023 saa7114_write_block(client, decoder->reg + (0xa8 << 1),
1024 8 << 1);
1025 err[18] =
1026 saa7114_write_block(client, decoder->reg + (0xb0 << 1),
1027 8 << 1);
1028 err[19] = saa7114_write_block(client, decoder->reg + (0xc0 << 1), 4 << 1); // Task B
1029 err[15] =
1030 saa7114_write_block(client, decoder->reg + (0xc4 << 1),
1031 12 << 1);
1032 err[16] =
1033 saa7114_write_block(client, decoder->reg + (0xd0 << 1),
1034 8 << 1);
1035 err[17] =
1036 saa7114_write_block(client, decoder->reg + (0xd8 << 1),
1037 8 << 1);
1038 err[18] =
1039 saa7114_write_block(client, decoder->reg + (0xe0 << 1),
1040 8 << 1);
1042 for (i = 9; i <= 18; i++) {
1043 if (err[i] < 0) {
1044 dprintk(1,
1045 KERN_ERR
1046 "%s_attach: init error %d at stage %d, leaving attach.\n",
1047 I2C_NAME(client), i, err[i]);
1048 kfree(decoder);
1049 kfree(client);
1050 return 0;
1055 for (i = 6; i < 8; i++) {
1056 dprintk(1,
1057 KERN_DEBUG
1058 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
1059 I2C_NAME(client), i, saa7114_read(client, i),
1060 decoder->reg[REG_ADDR(i)]);
1064 for (i = 0x11; i <= 0x13; i++) {
1065 dprintk(1,
1066 KERN_DEBUG
1067 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
1068 I2C_NAME(client), i, saa7114_read(client, i),
1069 decoder->reg[REG_ADDR(i)]);
1073 dprintk(1, KERN_DEBUG "%s_attach: setting video input\n",
1074 I2C_NAME(client));
1076 err[19] =
1077 saa7114_write(client, 0x02, decoder->reg[REG_ADDR(0x02)]);
1078 err[20] =
1079 saa7114_write(client, 0x09, decoder->reg[REG_ADDR(0x09)]);
1080 err[21] =
1081 saa7114_write(client, 0x0e, decoder->reg[REG_ADDR(0x0e)]);
1083 for (i = 19; i <= 21; i++) {
1084 if (err[i] < 0) {
1085 dprintk(1,
1086 KERN_ERR
1087 "%s_attach: init error %d at stage %d, leaving attach.\n",
1088 I2C_NAME(client), i, err[i]);
1089 kfree(decoder);
1090 kfree(client);
1091 return 0;
1095 dprintk(1,
1096 KERN_DEBUG
1097 "%s_attach: performing decoder reset sequence\n",
1098 I2C_NAME(client));
1100 err[22] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler
1101 err[23] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
1102 err[24] = saa7114_write(client, 0x80, 0x36); // i-port and scaler backend clock selection, task A&B off
1105 for (i = 22; i <= 24; i++) {
1106 if (err[i] < 0) {
1107 dprintk(1,
1108 KERN_ERR
1109 "%s_attach: init error %d at stage %d, leaving attach.\n",
1110 I2C_NAME(client), i, err[i]);
1111 kfree(decoder);
1112 kfree(client);
1113 return 0;
1117 err[25] = saa7114_write(client, 0x06, init[REG_ADDR(0x06)]);
1118 err[26] = saa7114_write(client, 0x07, init[REG_ADDR(0x07)]);
1119 err[27] = saa7114_write(client, 0x10, init[REG_ADDR(0x10)]);
1121 dprintk(1,
1122 KERN_INFO
1123 "%s_attach: chip version %x, decoder status 0x%02x\n",
1124 I2C_NAME(client), saa7114_read(client, 0x00) >> 4,
1125 saa7114_read(client, 0x1f));
1126 dprintk(1,
1127 KERN_DEBUG
1128 "%s_attach: power save control: 0x%02x, scaler status: 0x%02x\n",
1129 I2C_NAME(client), saa7114_read(client, 0x88),
1130 saa7114_read(client, 0x8f));
1133 for (i = 0x94; i < 0x96; i++) {
1134 dprintk(1,
1135 KERN_DEBUG
1136 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
1137 I2C_NAME(client), i, saa7114_read(client, i),
1138 decoder->reg[REG_ADDR(i)]);
1141 i = i2c_attach_client(client);
1142 if (i) {
1143 kfree(client);
1144 kfree(decoder);
1145 return i;
1148 //i = saa7114_write_block(client, init, sizeof(init));
1149 i = 0;
1150 if (i < 0) {
1151 dprintk(1, KERN_ERR "%s_attach error: init status %d\n",
1152 I2C_NAME(client), i);
1153 } else {
1154 dprintk(1,
1155 KERN_INFO
1156 "%s_attach: chip version %x at address 0x%x\n",
1157 I2C_NAME(client), saa7114_read(client, 0x00) >> 4,
1158 client->addr << 1);
1161 return 0;
1164 static int
1165 saa7114_attach_adapter (struct i2c_adapter *adapter)
1167 dprintk(1,
1168 KERN_INFO
1169 "saa7114.c: starting probe for adapter %s (0x%x)\n",
1170 I2C_NAME(adapter), adapter->id);
1171 return i2c_probe(adapter, &addr_data, &saa7114_detect_client);
1174 static int
1175 saa7114_detach_client (struct i2c_client *client)
1177 struct saa7114 *decoder = i2c_get_clientdata(client);
1178 int err;
1180 err = i2c_detach_client(client);
1181 if (err) {
1182 return err;
1185 kfree(decoder);
1186 kfree(client);
1188 return 0;
1191 /* ----------------------------------------------------------------------- */
1193 static struct i2c_driver i2c_driver_saa7114 = {
1194 .driver = {
1195 .name = "saa7114",
1198 .id = I2C_DRIVERID_SAA7114,
1200 .attach_adapter = saa7114_attach_adapter,
1201 .detach_client = saa7114_detach_client,
1202 .command = saa7114_command,
1205 static int __init
1206 saa7114_init (void)
1208 return i2c_add_driver(&i2c_driver_saa7114);
1211 static void __exit
1212 saa7114_exit (void)
1214 i2c_del_driver(&i2c_driver_saa7114);
1217 module_init(saa7114_init);
1218 module_exit(saa7114_exit);