[PATCH] UHCI: unify BIOS handoff and driver reset code
[linux-2.6/suspend2-2.6.18.git] / drivers / media / video / saa7114.c
blobd9f50e2f7b92f1c14997945c465ffdc13fad668c
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>
58 #include <linux/i2c-dev.h>
60 #define I2C_NAME(x) (x)->name
62 #include <linux/video_decoder.h>
64 static int debug = 0;
65 module_param(debug, int, 0);
66 MODULE_PARM_DESC(debug, "Debug level (0-1)");
68 #define dprintk(num, format, args...) \
69 do { \
70 if (debug >= num) \
71 printk(format, ##args); \
72 } while (0)
74 /* ----------------------------------------------------------------------- */
76 struct saa7114 {
77 unsigned char reg[0xf0 * 2];
79 int norm;
80 int input;
81 int enable;
82 int bright;
83 int contrast;
84 int hue;
85 int sat;
86 int playback;
89 #define I2C_SAA7114 0x42
90 #define I2C_SAA7114A 0x40
92 #define I2C_DELAY 10
95 //#define SAA_7114_NTSC_HSYNC_START (-3)
96 //#define SAA_7114_NTSC_HSYNC_STOP (-18)
98 #define SAA_7114_NTSC_HSYNC_START (-17)
99 #define SAA_7114_NTSC_HSYNC_STOP (-32)
101 //#define SAA_7114_NTSC_HOFFSET (5)
102 #define SAA_7114_NTSC_HOFFSET (6)
103 #define SAA_7114_NTSC_VOFFSET (10)
104 #define SAA_7114_NTSC_WIDTH (720)
105 #define SAA_7114_NTSC_HEIGHT (250)
107 #define SAA_7114_SECAM_HSYNC_START (-17)
108 #define SAA_7114_SECAM_HSYNC_STOP (-32)
110 #define SAA_7114_SECAM_HOFFSET (2)
111 #define SAA_7114_SECAM_VOFFSET (10)
112 #define SAA_7114_SECAM_WIDTH (720)
113 #define SAA_7114_SECAM_HEIGHT (300)
115 #define SAA_7114_PAL_HSYNC_START (-17)
116 #define SAA_7114_PAL_HSYNC_STOP (-32)
118 #define SAA_7114_PAL_HOFFSET (2)
119 #define SAA_7114_PAL_VOFFSET (10)
120 #define SAA_7114_PAL_WIDTH (720)
121 #define SAA_7114_PAL_HEIGHT (300)
125 #define SAA_7114_VERTICAL_CHROMA_OFFSET 0 //0x50504040
126 #define SAA_7114_VERTICAL_LUMA_OFFSET 0
128 #define REG_ADDR(x) (((x) << 1) + 1)
129 #define LOBYTE(x) ((unsigned char)((x) & 0xff))
130 #define HIBYTE(x) ((unsigned char)(((x) >> 8) & 0xff))
131 #define LOWORD(x) ((unsigned short int)((x) & 0xffff))
132 #define HIWORD(x) ((unsigned short int)(((x) >> 16) & 0xffff))
135 /* ----------------------------------------------------------------------- */
137 static inline int
138 saa7114_write (struct i2c_client *client,
139 u8 reg,
140 u8 value)
142 /*struct saa7114 *decoder = i2c_get_clientdata(client);*/
144 /*decoder->reg[reg] = value;*/
145 return i2c_smbus_write_byte_data(client, reg, value);
148 static int
149 saa7114_write_block (struct i2c_client *client,
150 const u8 *data,
151 unsigned int len)
153 int ret = -1;
154 u8 reg;
156 /* the saa7114 has an autoincrement function, use it if
157 * the adapter understands raw I2C */
158 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
159 /* do raw I2C, not smbus compatible */
160 /*struct saa7114 *decoder = i2c_get_clientdata(client);*/
161 struct i2c_msg msg;
162 u8 block_data[32];
164 msg.addr = client->addr;
165 msg.flags = 0;
166 while (len >= 2) {
167 msg.buf = (char *) block_data;
168 msg.len = 0;
169 block_data[msg.len++] = reg = data[0];
170 do {
171 block_data[msg.len++] =
172 /*decoder->reg[reg++] =*/ data[1];
173 len -= 2;
174 data += 2;
175 } while (len >= 2 && data[0] == reg &&
176 msg.len < 32);
177 if ((ret = i2c_transfer(client->adapter,
178 &msg, 1)) < 0)
179 break;
181 } else {
182 /* do some slow I2C emulation kind of thing */
183 while (len >= 2) {
184 reg = *data++;
185 if ((ret = saa7114_write(client, reg,
186 *data++)) < 0)
187 break;
188 len -= 2;
192 return ret;
195 static inline int
196 saa7114_read (struct i2c_client *client,
197 u8 reg)
199 return i2c_smbus_read_byte_data(client, reg);
202 /* ----------------------------------------------------------------------- */
204 // initially set NTSC, composite
207 static const unsigned char init[] = {
208 0x00, 0x00, /* 00 - ID byte , chip version,
209 * read only */
210 0x01, 0x08, /* 01 - X,X,X,X, IDEL3 to IDEL0 -
211 * horizontal increment delay,
212 * recommended position */
213 0x02, 0x00, /* 02 - FUSE=3, GUDL=2, MODE=0 ;
214 * input control */
215 0x03, 0x10, /* 03 - HLNRS=0, VBSL=1, WPOFF=0,
216 * HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
217 0x04, 0x90, /* 04 - GAI1=256 */
218 0x05, 0x90, /* 05 - GAI2=256 */
219 0x06, SAA_7114_NTSC_HSYNC_START, /* 06 - HSB: hsync start,
220 * depends on the video standard */
221 0x07, SAA_7114_NTSC_HSYNC_STOP, /* 07 - HSS: hsync stop, depends
222 *on the video standard */
223 0x08, 0xb8, /* 08 - AUFD=1, FSEL=1, EXFIL=0, VTRC=1,
224 * HPLL: free running in playback, locked
225 * in capture, VNOI=0 */
226 0x09, 0x80, /* 09 - BYPS=0, PREF=0, BPSS=0, VBLB=0,
227 * UPTCV=0, APER=1; depends from input */
228 0x0a, 0x80, /* 0a - BRIG=128 */
229 0x0b, 0x44, /* 0b - CONT=1.109 */
230 0x0c, 0x40, /* 0c - SATN=1.0 */
231 0x0d, 0x00, /* 0d - HUE=0 */
232 0x0e, 0x84, /* 0e - CDTO, CSTD2 to 0, DCVF, FCTC,
233 * CCOMB; depends from video standard */
234 0x0f, 0x24, /* 0f - ACGC,CGAIN6 to CGAIN0; depends
235 * from video standard */
236 0x10, 0x03, /* 10 - OFFU1 to 0, OFFV1 to 0, CHBW,
237 * LCBW2 to 0 */
238 0x11, 0x59, /* 11 - COLO, RTP1, HEDL1 to 0, RTP0,
239 * YDEL2 to 0 */
240 0x12, 0xc9, /* 12 - RT signal control RTSE13 to 10
241 * and 03 to 00 */
242 0x13, 0x80, /* 13 - RT/X port output control */
243 0x14, 0x00, /* 14 - analog, ADC, compatibility control */
244 0x15, 0x00, /* 15 - VGATE start FID change */
245 0x16, 0xfe, /* 16 - VGATE stop */
246 0x17, 0x00, /* 17 - Misc., VGATE MSBs */
247 0x18, 0x40, /* RAWG */
248 0x19, 0x80, /* RAWO */
249 0x1a, 0x00,
250 0x1b, 0x00,
251 0x1c, 0x00,
252 0x1d, 0x00,
253 0x1e, 0x00,
254 0x1f, 0x00, /* status byte, read only */
255 0x20, 0x00, /* video decoder reserved part */
256 0x21, 0x00,
257 0x22, 0x00,
258 0x23, 0x00,
259 0x24, 0x00,
260 0x25, 0x00,
261 0x26, 0x00,
262 0x27, 0x00,
263 0x28, 0x00,
264 0x29, 0x00,
265 0x2a, 0x00,
266 0x2b, 0x00,
267 0x2c, 0x00,
268 0x2d, 0x00,
269 0x2e, 0x00,
270 0x2f, 0x00,
271 0x30, 0xbc, /* audio clock generator */
272 0x31, 0xdf,
273 0x32, 0x02,
274 0x33, 0x00,
275 0x34, 0xcd,
276 0x35, 0xcc,
277 0x36, 0x3a,
278 0x37, 0x00,
279 0x38, 0x03,
280 0x39, 0x10,
281 0x3a, 0x00,
282 0x3b, 0x00,
283 0x3c, 0x00,
284 0x3d, 0x00,
285 0x3e, 0x00,
286 0x3f, 0x00,
287 0x40, 0x00, /* VBI data slicer */
288 0x41, 0xff,
289 0x42, 0xff,
290 0x43, 0xff,
291 0x44, 0xff,
292 0x45, 0xff,
293 0x46, 0xff,
294 0x47, 0xff,
295 0x48, 0xff,
296 0x49, 0xff,
297 0x4a, 0xff,
298 0x4b, 0xff,
299 0x4c, 0xff,
300 0x4d, 0xff,
301 0x4e, 0xff,
302 0x4f, 0xff,
303 0x50, 0xff,
304 0x51, 0xff,
305 0x52, 0xff,
306 0x53, 0xff,
307 0x54, 0xff,
308 0x55, 0xff,
309 0x56, 0xff,
310 0x57, 0xff,
311 0x58, 0x40, // framing code
312 0x59, 0x47, // horizontal offset
313 0x5a, 0x06, // vertical offset
314 0x5b, 0x83, // field offset
315 0x5c, 0x00, // reserved
316 0x5d, 0x3e, // header and data
317 0x5e, 0x00, // sliced data
318 0x5f, 0x00, // reserved
319 0x60, 0x00, /* video decoder reserved part */
320 0x61, 0x00,
321 0x62, 0x00,
322 0x63, 0x00,
323 0x64, 0x00,
324 0x65, 0x00,
325 0x66, 0x00,
326 0x67, 0x00,
327 0x68, 0x00,
328 0x69, 0x00,
329 0x6a, 0x00,
330 0x6b, 0x00,
331 0x6c, 0x00,
332 0x6d, 0x00,
333 0x6e, 0x00,
334 0x6f, 0x00,
335 0x70, 0x00, /* video decoder reserved part */
336 0x71, 0x00,
337 0x72, 0x00,
338 0x73, 0x00,
339 0x74, 0x00,
340 0x75, 0x00,
341 0x76, 0x00,
342 0x77, 0x00,
343 0x78, 0x00,
344 0x79, 0x00,
345 0x7a, 0x00,
346 0x7b, 0x00,
347 0x7c, 0x00,
348 0x7d, 0x00,
349 0x7e, 0x00,
350 0x7f, 0x00,
351 0x80, 0x00, /* X-port, I-port and scaler */
352 0x81, 0x00,
353 0x82, 0x00,
354 0x83, 0x00,
355 0x84, 0xc5,
356 0x85, 0x0d, // hsync and vsync ?
357 0x86, 0x40,
358 0x87, 0x01,
359 0x88, 0x00,
360 0x89, 0x00,
361 0x8a, 0x00,
362 0x8b, 0x00,
363 0x8c, 0x00,
364 0x8d, 0x00,
365 0x8e, 0x00,
366 0x8f, 0x00,
367 0x90, 0x03, /* Task A definition */
368 0x91, 0x08,
369 0x92, 0x00,
370 0x93, 0x40,
371 0x94, 0x00, // window settings
372 0x95, 0x00,
373 0x96, 0x00,
374 0x97, 0x00,
375 0x98, 0x00,
376 0x99, 0x00,
377 0x9a, 0x00,
378 0x9b, 0x00,
379 0x9c, 0x00,
380 0x9d, 0x00,
381 0x9e, 0x00,
382 0x9f, 0x00,
383 0xa0, 0x01, /* horizontal integer prescaling ratio */
384 0xa1, 0x00, /* horizontal prescaler accumulation
385 * sequence length */
386 0xa2, 0x00, /* UV FIR filter, Y FIR filter, prescaler
387 * DC gain */
388 0xa3, 0x00,
389 0xa4, 0x80, // luminance brightness
390 0xa5, 0x40, // luminance gain
391 0xa6, 0x40, // chrominance saturation
392 0xa7, 0x00,
393 0xa8, 0x00, // horizontal luminance scaling increment
394 0xa9, 0x04,
395 0xaa, 0x00, // horizontal luminance phase offset
396 0xab, 0x00,
397 0xac, 0x00, // horizontal chrominance scaling increment
398 0xad, 0x02,
399 0xae, 0x00, // horizontal chrominance phase offset
400 0xaf, 0x00,
401 0xb0, 0x00, // vertical luminance scaling increment
402 0xb1, 0x04,
403 0xb2, 0x00, // vertical chrominance scaling increment
404 0xb3, 0x04,
405 0xb4, 0x00,
406 0xb5, 0x00,
407 0xb6, 0x00,
408 0xb7, 0x00,
409 0xb8, 0x00,
410 0xb9, 0x00,
411 0xba, 0x00,
412 0xbb, 0x00,
413 0xbc, 0x00,
414 0xbd, 0x00,
415 0xbe, 0x00,
416 0xbf, 0x00,
417 0xc0, 0x02, // Task B definition
418 0xc1, 0x08,
419 0xc2, 0x00,
420 0xc3, 0x40,
421 0xc4, 0x00, // window settings
422 0xc5, 0x00,
423 0xc6, 0x00,
424 0xc7, 0x00,
425 0xc8, 0x00,
426 0xc9, 0x00,
427 0xca, 0x00,
428 0xcb, 0x00,
429 0xcc, 0x00,
430 0xcd, 0x00,
431 0xce, 0x00,
432 0xcf, 0x00,
433 0xd0, 0x01, // horizontal integer prescaling ratio
434 0xd1, 0x00, // horizontal prescaler accumulation sequence length
435 0xd2, 0x00, // UV FIR filter, Y FIR filter, prescaler DC gain
436 0xd3, 0x00,
437 0xd4, 0x80, // luminance brightness
438 0xd5, 0x40, // luminance gain
439 0xd6, 0x40, // chrominance saturation
440 0xd7, 0x00,
441 0xd8, 0x00, // horizontal luminance scaling increment
442 0xd9, 0x04,
443 0xda, 0x00, // horizontal luminance phase offset
444 0xdb, 0x00,
445 0xdc, 0x00, // horizontal chrominance scaling increment
446 0xdd, 0x02,
447 0xde, 0x00, // horizontal chrominance phase offset
448 0xdf, 0x00,
449 0xe0, 0x00, // vertical luminance scaling increment
450 0xe1, 0x04,
451 0xe2, 0x00, // vertical chrominance scaling increment
452 0xe3, 0x04,
453 0xe4, 0x00,
454 0xe5, 0x00,
455 0xe6, 0x00,
456 0xe7, 0x00,
457 0xe8, 0x00,
458 0xe9, 0x00,
459 0xea, 0x00,
460 0xeb, 0x00,
461 0xec, 0x00,
462 0xed, 0x00,
463 0xee, 0x00,
464 0xef, 0x00
467 static int
468 saa7114_command (struct i2c_client *client,
469 unsigned int cmd,
470 void *arg)
472 struct saa7114 *decoder = i2c_get_clientdata(client);
474 switch (cmd) {
476 case 0:
477 //dprintk(1, KERN_INFO "%s: writing init\n", I2C_NAME(client));
478 //saa7114_write_block(client, init, sizeof(init));
479 break;
481 case DECODER_DUMP:
483 int i;
485 dprintk(1, KERN_INFO "%s: decoder dump\n", I2C_NAME(client));
487 for (i = 0; i < 32; i += 16) {
488 int j;
490 printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i);
491 for (j = 0; j < 16; ++j) {
492 printk(" %02x",
493 saa7114_read(client, i + j));
495 printk("\n");
498 break;
500 case DECODER_GET_CAPABILITIES:
502 struct video_decoder_capability *cap = arg;
504 dprintk(1, KERN_DEBUG "%s: decoder get capabilities\n",
505 I2C_NAME(client));
507 cap->flags = VIDEO_DECODER_PAL |
508 VIDEO_DECODER_NTSC |
509 VIDEO_DECODER_AUTO |
510 VIDEO_DECODER_CCIR;
511 cap->inputs = 8;
512 cap->outputs = 1;
514 break;
516 case DECODER_GET_STATUS:
518 int *iarg = arg;
519 int status;
520 int res;
522 status = saa7114_read(client, 0x1f);
524 dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client),
525 status);
526 res = 0;
527 if ((status & (1 << 6)) == 0) {
528 res |= DECODER_STATUS_GOOD;
530 switch (decoder->norm) {
531 case VIDEO_MODE_NTSC:
532 res |= DECODER_STATUS_NTSC;
533 break;
534 case VIDEO_MODE_PAL:
535 res |= DECODER_STATUS_PAL;
536 break;
537 case VIDEO_MODE_SECAM:
538 res |= DECODER_STATUS_SECAM;
539 break;
540 default:
541 case VIDEO_MODE_AUTO:
542 if ((status & (1 << 5)) != 0) {
543 res |= DECODER_STATUS_NTSC;
544 } else {
545 res |= DECODER_STATUS_PAL;
547 break;
549 if ((status & (1 << 0)) != 0) {
550 res |= DECODER_STATUS_COLOR;
552 *iarg = res;
554 break;
556 case DECODER_SET_NORM:
558 int *iarg = arg;
560 short int hoff = 0, voff = 0, w = 0, h = 0;
562 dprintk(1, KERN_DEBUG "%s: decoder set norm ",
563 I2C_NAME(client));
564 switch (*iarg) {
566 case VIDEO_MODE_NTSC:
567 dprintk(1, "NTSC\n");
568 decoder->reg[REG_ADDR(0x06)] =
569 SAA_7114_NTSC_HSYNC_START;
570 decoder->reg[REG_ADDR(0x07)] =
571 SAA_7114_NTSC_HSYNC_STOP;
573 decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8; // PLL free when playback, PLL close when capture
575 decoder->reg[REG_ADDR(0x0e)] = 0x85;
576 decoder->reg[REG_ADDR(0x0f)] = 0x24;
578 hoff = SAA_7114_NTSC_HOFFSET;
579 voff = SAA_7114_NTSC_VOFFSET;
580 w = SAA_7114_NTSC_WIDTH;
581 h = SAA_7114_NTSC_HEIGHT;
583 break;
585 case VIDEO_MODE_PAL:
586 dprintk(1, "PAL\n");
587 decoder->reg[REG_ADDR(0x06)] =
588 SAA_7114_PAL_HSYNC_START;
589 decoder->reg[REG_ADDR(0x07)] =
590 SAA_7114_PAL_HSYNC_STOP;
592 decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8; // PLL free when playback, PLL close when capture
594 decoder->reg[REG_ADDR(0x0e)] = 0x81;
595 decoder->reg[REG_ADDR(0x0f)] = 0x24;
597 hoff = SAA_7114_PAL_HOFFSET;
598 voff = SAA_7114_PAL_VOFFSET;
599 w = SAA_7114_PAL_WIDTH;
600 h = SAA_7114_PAL_HEIGHT;
602 break;
604 default:
605 dprintk(1, " Unknown video mode!!!\n");
606 return -EINVAL;
611 decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff); // hoffset low
612 decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f; // hoffset high
613 decoder->reg[REG_ADDR(0x96)] = LOBYTE(w); // width low
614 decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f; // width high
615 decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff); // voffset low
616 decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f; // voffset high
617 decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2); // height low
618 decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f; // height high
619 decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w); // out width low
620 decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f; // out width high
621 decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h); // out height low
622 decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f; // out height high
624 decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff); // hoffset low
625 decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f; // hoffset high
626 decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w); // width low
627 decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f; // width high
628 decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff); // voffset low
629 decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f; // voffset high
630 decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2); // height low
631 decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f; // height high
632 decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w); // out width low
633 decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f; // out width high
634 decoder->reg[REG_ADDR(0xce)] = LOBYTE(h); // out height low
635 decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f; // out height high
638 saa7114_write(client, 0x80, 0x06); // i-port and scaler back end clock selection, task A&B off
639 saa7114_write(client, 0x88, 0xd8); // sw reset scaler
640 saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
642 saa7114_write_block(client, decoder->reg + (0x06 << 1),
643 3 << 1);
644 saa7114_write_block(client, decoder->reg + (0x0e << 1),
645 2 << 1);
646 saa7114_write_block(client, decoder->reg + (0x5a << 1),
647 2 << 1);
649 saa7114_write_block(client, decoder->reg + (0x94 << 1),
650 (0x9f + 1 - 0x94) << 1);
651 saa7114_write_block(client, decoder->reg + (0xc4 << 1),
652 (0xcf + 1 - 0xc4) << 1);
654 saa7114_write(client, 0x88, 0xd8); // sw reset scaler
655 saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
656 saa7114_write(client, 0x80, 0x36); // i-port and scaler back end clock selection
658 decoder->norm = *iarg;
660 break;
662 case DECODER_SET_INPUT:
664 int *iarg = arg;
666 dprintk(1, KERN_DEBUG "%s: decoder set input (%d)\n",
667 I2C_NAME(client), *iarg);
668 if (*iarg < 0 || *iarg > 7) {
669 return -EINVAL;
672 if (decoder->input != *iarg) {
673 dprintk(1, KERN_DEBUG "%s: now setting %s input\n",
674 I2C_NAME(client),
675 *iarg >= 6 ? "S-Video" : "Composite");
676 decoder->input = *iarg;
678 /* select mode */
679 decoder->reg[REG_ADDR(0x02)] =
680 (decoder->
681 reg[REG_ADDR(0x02)] & 0xf0) | (decoder->
682 input <
683 6 ? 0x0 : 0x9);
684 saa7114_write(client, 0x02,
685 decoder->reg[REG_ADDR(0x02)]);
687 /* bypass chrominance trap for modes 6..9 */
688 decoder->reg[REG_ADDR(0x09)] =
689 (decoder->
690 reg[REG_ADDR(0x09)] & 0x7f) | (decoder->
691 input <
692 6 ? 0x0 :
693 0x80);
694 saa7114_write(client, 0x09,
695 decoder->reg[REG_ADDR(0x09)]);
697 decoder->reg[REG_ADDR(0x0e)] =
698 decoder->input <
699 6 ? decoder->
700 reg[REG_ADDR(0x0e)] | 1 : decoder->
701 reg[REG_ADDR(0x0e)] & ~1;
702 saa7114_write(client, 0x0e,
703 decoder->reg[REG_ADDR(0x0e)]);
706 break;
708 case DECODER_SET_OUTPUT:
710 int *iarg = arg;
712 dprintk(1, KERN_DEBUG "%s: decoder set output\n",
713 I2C_NAME(client));
715 /* not much choice of outputs */
716 if (*iarg != 0) {
717 return -EINVAL;
720 break;
722 case DECODER_ENABLE_OUTPUT:
724 int *iarg = arg;
725 int enable = (*iarg != 0);
727 dprintk(1, KERN_DEBUG "%s: decoder %s output\n",
728 I2C_NAME(client), enable ? "enable" : "disable");
730 decoder->playback = !enable;
732 if (decoder->enable != enable) {
733 decoder->enable = enable;
735 /* RJ: If output should be disabled (for
736 * playing videos), we also need a open PLL.
737 * The input is set to 0 (where no input
738 * source is connected), although this
739 * is not necessary.
741 * If output should be enabled, we have to
742 * reverse the above.
745 if (decoder->enable) {
746 decoder->reg[REG_ADDR(0x08)] = 0xb8;
747 decoder->reg[REG_ADDR(0x12)] = 0xc9;
748 decoder->reg[REG_ADDR(0x13)] = 0x80;
749 decoder->reg[REG_ADDR(0x87)] = 0x01;
750 } else {
751 decoder->reg[REG_ADDR(0x08)] = 0x7c;
752 decoder->reg[REG_ADDR(0x12)] = 0x00;
753 decoder->reg[REG_ADDR(0x13)] = 0x00;
754 decoder->reg[REG_ADDR(0x87)] = 0x00;
757 saa7114_write_block(client,
758 decoder->reg + (0x12 << 1),
759 2 << 1);
760 saa7114_write(client, 0x08,
761 decoder->reg[REG_ADDR(0x08)]);
762 saa7114_write(client, 0x87,
763 decoder->reg[REG_ADDR(0x87)]);
764 saa7114_write(client, 0x88, 0xd8); // sw reset scaler
765 saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
766 saa7114_write(client, 0x80, 0x36);
770 break;
772 case DECODER_SET_PICTURE:
774 struct video_picture *pic = arg;
776 dprintk(1,
777 KERN_DEBUG
778 "%s: decoder set picture bright=%d contrast=%d saturation=%d hue=%d\n",
779 I2C_NAME(client), pic->brightness, pic->contrast,
780 pic->colour, pic->hue);
782 if (decoder->bright != pic->brightness) {
783 /* We want 0 to 255 we get 0-65535 */
784 decoder->bright = pic->brightness;
785 saa7114_write(client, 0x0a, decoder->bright >> 8);
787 if (decoder->contrast != pic->contrast) {
788 /* We want 0 to 127 we get 0-65535 */
789 decoder->contrast = pic->contrast;
790 saa7114_write(client, 0x0b,
791 decoder->contrast >> 9);
793 if (decoder->sat != pic->colour) {
794 /* We want 0 to 127 we get 0-65535 */
795 decoder->sat = pic->colour;
796 saa7114_write(client, 0x0c, decoder->sat >> 9);
798 if (decoder->hue != pic->hue) {
799 /* We want -128 to 127 we get 0-65535 */
800 decoder->hue = pic->hue;
801 saa7114_write(client, 0x0d,
802 (decoder->hue - 32768) >> 8);
805 break;
807 default:
808 return -EINVAL;
811 return 0;
814 /* ----------------------------------------------------------------------- */
817 * Generic i2c probe
818 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
820 static unsigned short normal_i2c[] =
821 { I2C_SAA7114 >> 1, I2C_SAA7114A >> 1, I2C_CLIENT_END };
823 static unsigned short ignore = I2C_CLIENT_END;
825 static struct i2c_client_address_data addr_data = {
826 .normal_i2c = normal_i2c,
827 .probe = &ignore,
828 .ignore = &ignore,
831 static struct i2c_driver i2c_driver_saa7114;
833 static int
834 saa7114_detect_client (struct i2c_adapter *adapter,
835 int address,
836 int kind)
838 int i, err[30];
839 short int hoff = SAA_7114_NTSC_HOFFSET;
840 short int voff = SAA_7114_NTSC_VOFFSET;
841 short int w = SAA_7114_NTSC_WIDTH;
842 short int h = SAA_7114_NTSC_HEIGHT;
843 struct i2c_client *client;
844 struct saa7114 *decoder;
846 dprintk(1,
847 KERN_INFO
848 "saa7114.c: detecting saa7114 client on address 0x%x\n",
849 address << 1);
851 /* Check if the adapter supports the needed features */
852 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
853 return 0;
855 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
856 if (client == 0)
857 return -ENOMEM;
858 memset(client, 0, sizeof(struct i2c_client));
859 client->addr = address;
860 client->adapter = adapter;
861 client->driver = &i2c_driver_saa7114;
862 client->flags = I2C_CLIENT_ALLOW_USE;
863 strlcpy(I2C_NAME(client), "saa7114", sizeof(I2C_NAME(client)));
865 decoder = kmalloc(sizeof(struct saa7114), GFP_KERNEL);
866 if (decoder == NULL) {
867 kfree(client);
868 return -ENOMEM;
870 memset(decoder, 0, sizeof(struct saa7114));
871 decoder->norm = VIDEO_MODE_NTSC;
872 decoder->input = -1;
873 decoder->enable = 1;
874 decoder->bright = 32768;
875 decoder->contrast = 32768;
876 decoder->hue = 32768;
877 decoder->sat = 32768;
878 decoder->playback = 0; // initially capture mode useda
879 i2c_set_clientdata(client, decoder);
881 memcpy(decoder->reg, init, sizeof(init));
883 decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff); // hoffset low
884 decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f; // hoffset high
885 decoder->reg[REG_ADDR(0x96)] = LOBYTE(w); // width low
886 decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f; // width high
887 decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff); // voffset low
888 decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f; // voffset high
889 decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2); // height low
890 decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f; // height high
891 decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w); // out width low
892 decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f; // out width high
893 decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h); // out height low
894 decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f; // out height high
896 decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff); // hoffset low
897 decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f; // hoffset high
898 decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w); // width low
899 decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f; // width high
900 decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff); // voffset low
901 decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f; // voffset high
902 decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2); // height low
903 decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f; // height high
904 decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w); // out width low
905 decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f; // out width high
906 decoder->reg[REG_ADDR(0xce)] = LOBYTE(h); // out height low
907 decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f; // out height high
909 decoder->reg[REG_ADDR(0xb8)] =
910 LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
911 decoder->reg[REG_ADDR(0xb9)] =
912 HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
913 decoder->reg[REG_ADDR(0xba)] =
914 LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
915 decoder->reg[REG_ADDR(0xbb)] =
916 HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
918 decoder->reg[REG_ADDR(0xbc)] =
919 LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
920 decoder->reg[REG_ADDR(0xbd)] =
921 HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
922 decoder->reg[REG_ADDR(0xbe)] =
923 LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
924 decoder->reg[REG_ADDR(0xbf)] =
925 HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
927 decoder->reg[REG_ADDR(0xe8)] =
928 LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
929 decoder->reg[REG_ADDR(0xe9)] =
930 HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
931 decoder->reg[REG_ADDR(0xea)] =
932 LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
933 decoder->reg[REG_ADDR(0xeb)] =
934 HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
936 decoder->reg[REG_ADDR(0xec)] =
937 LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
938 decoder->reg[REG_ADDR(0xed)] =
939 HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
940 decoder->reg[REG_ADDR(0xee)] =
941 LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
942 decoder->reg[REG_ADDR(0xef)] =
943 HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
946 decoder->reg[REG_ADDR(0x13)] = 0x80; // RTC0 on
947 decoder->reg[REG_ADDR(0x87)] = 0x01; // I-Port
948 decoder->reg[REG_ADDR(0x12)] = 0xc9; // RTS0
950 decoder->reg[REG_ADDR(0x02)] = 0xc0; // set composite1 input, aveasy
951 decoder->reg[REG_ADDR(0x09)] = 0x00; // chrominance trap
952 decoder->reg[REG_ADDR(0x0e)] |= 1; // combfilter on
955 dprintk(1, KERN_DEBUG "%s_attach: starting decoder init\n",
956 I2C_NAME(client));
958 err[0] =
959 saa7114_write_block(client, decoder->reg + (0x20 << 1),
960 0x10 << 1);
961 err[1] =
962 saa7114_write_block(client, decoder->reg + (0x30 << 1),
963 0x10 << 1);
964 err[2] =
965 saa7114_write_block(client, decoder->reg + (0x63 << 1),
966 (0x7f + 1 - 0x63) << 1);
967 err[3] =
968 saa7114_write_block(client, decoder->reg + (0x89 << 1),
969 6 << 1);
970 err[4] =
971 saa7114_write_block(client, decoder->reg + (0xb8 << 1),
972 8 << 1);
973 err[5] =
974 saa7114_write_block(client, decoder->reg + (0xe8 << 1),
975 8 << 1);
978 for (i = 0; i <= 5; i++) {
979 if (err[i] < 0) {
980 dprintk(1,
981 KERN_ERR
982 "%s_attach: init error %d at stage %d, leaving attach.\n",
983 I2C_NAME(client), i, err[i]);
984 kfree(decoder);
985 kfree(client);
986 return 0;
990 for (i = 6; i < 8; i++) {
991 dprintk(1,
992 KERN_DEBUG
993 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
994 I2C_NAME(client), i, saa7114_read(client, i),
995 decoder->reg[REG_ADDR(i)]);
998 dprintk(1,
999 KERN_DEBUG
1000 "%s_attach: performing decoder reset sequence\n",
1001 I2C_NAME(client));
1003 err[6] = saa7114_write(client, 0x80, 0x06); // i-port and scaler backend clock selection, task A&B off
1004 err[7] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler
1005 err[8] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
1007 for (i = 6; i <= 8; i++) {
1008 if (err[i] < 0) {
1009 dprintk(1,
1010 KERN_ERR
1011 "%s_attach: init error %d at stage %d, leaving attach.\n",
1012 I2C_NAME(client), i, err[i]);
1013 kfree(decoder);
1014 kfree(client);
1015 return 0;
1019 dprintk(1, KERN_INFO "%s_attach: performing the rest of init\n",
1020 I2C_NAME(client));
1023 err[9] = saa7114_write(client, 0x01, decoder->reg[REG_ADDR(0x01)]);
1024 err[10] = saa7114_write_block(client, decoder->reg + (0x03 << 1), (0x1e + 1 - 0x03) << 1); // big seq
1025 err[11] = saa7114_write_block(client, decoder->reg + (0x40 << 1), (0x5f + 1 - 0x40) << 1); // slicer
1026 err[12] = saa7114_write_block(client, decoder->reg + (0x81 << 1), 2 << 1); // ?
1027 err[13] = saa7114_write_block(client, decoder->reg + (0x83 << 1), 5 << 1); // ?
1028 err[14] = saa7114_write_block(client, decoder->reg + (0x90 << 1), 4 << 1); // Task A
1029 err[15] =
1030 saa7114_write_block(client, decoder->reg + (0x94 << 1),
1031 12 << 1);
1032 err[16] =
1033 saa7114_write_block(client, decoder->reg + (0xa0 << 1),
1034 8 << 1);
1035 err[17] =
1036 saa7114_write_block(client, decoder->reg + (0xa8 << 1),
1037 8 << 1);
1038 err[18] =
1039 saa7114_write_block(client, decoder->reg + (0xb0 << 1),
1040 8 << 1);
1041 err[19] = saa7114_write_block(client, decoder->reg + (0xc0 << 1), 4 << 1); // Task B
1042 err[15] =
1043 saa7114_write_block(client, decoder->reg + (0xc4 << 1),
1044 12 << 1);
1045 err[16] =
1046 saa7114_write_block(client, decoder->reg + (0xd0 << 1),
1047 8 << 1);
1048 err[17] =
1049 saa7114_write_block(client, decoder->reg + (0xd8 << 1),
1050 8 << 1);
1051 err[18] =
1052 saa7114_write_block(client, decoder->reg + (0xe0 << 1),
1053 8 << 1);
1055 for (i = 9; i <= 18; i++) {
1056 if (err[i] < 0) {
1057 dprintk(1,
1058 KERN_ERR
1059 "%s_attach: init error %d at stage %d, leaving attach.\n",
1060 I2C_NAME(client), i, err[i]);
1061 kfree(decoder);
1062 kfree(client);
1063 return 0;
1068 for (i = 6; i < 8; i++) {
1069 dprintk(1,
1070 KERN_DEBUG
1071 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
1072 I2C_NAME(client), i, saa7114_read(client, i),
1073 decoder->reg[REG_ADDR(i)]);
1077 for (i = 0x11; i <= 0x13; i++) {
1078 dprintk(1,
1079 KERN_DEBUG
1080 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
1081 I2C_NAME(client), i, saa7114_read(client, i),
1082 decoder->reg[REG_ADDR(i)]);
1086 dprintk(1, KERN_DEBUG "%s_attach: setting video input\n",
1087 I2C_NAME(client));
1089 err[19] =
1090 saa7114_write(client, 0x02, decoder->reg[REG_ADDR(0x02)]);
1091 err[20] =
1092 saa7114_write(client, 0x09, decoder->reg[REG_ADDR(0x09)]);
1093 err[21] =
1094 saa7114_write(client, 0x0e, decoder->reg[REG_ADDR(0x0e)]);
1096 for (i = 19; i <= 21; i++) {
1097 if (err[i] < 0) {
1098 dprintk(1,
1099 KERN_ERR
1100 "%s_attach: init error %d at stage %d, leaving attach.\n",
1101 I2C_NAME(client), i, err[i]);
1102 kfree(decoder);
1103 kfree(client);
1104 return 0;
1108 dprintk(1,
1109 KERN_DEBUG
1110 "%s_attach: performing decoder reset sequence\n",
1111 I2C_NAME(client));
1113 err[22] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler
1114 err[23] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
1115 err[24] = saa7114_write(client, 0x80, 0x36); // i-port and scaler backend clock selection, task A&B off
1118 for (i = 22; i <= 24; i++) {
1119 if (err[i] < 0) {
1120 dprintk(1,
1121 KERN_ERR
1122 "%s_attach: init error %d at stage %d, leaving attach.\n",
1123 I2C_NAME(client), i, err[i]);
1124 kfree(decoder);
1125 kfree(client);
1126 return 0;
1130 err[25] = saa7114_write(client, 0x06, init[REG_ADDR(0x06)]);
1131 err[26] = saa7114_write(client, 0x07, init[REG_ADDR(0x07)]);
1132 err[27] = saa7114_write(client, 0x10, init[REG_ADDR(0x10)]);
1134 dprintk(1,
1135 KERN_INFO
1136 "%s_attach: chip version %x, decoder status 0x%02x\n",
1137 I2C_NAME(client), saa7114_read(client, 0x00) >> 4,
1138 saa7114_read(client, 0x1f));
1139 dprintk(1,
1140 KERN_DEBUG
1141 "%s_attach: power save control: 0x%02x, scaler status: 0x%02x\n",
1142 I2C_NAME(client), saa7114_read(client, 0x88),
1143 saa7114_read(client, 0x8f));
1146 for (i = 0x94; i < 0x96; i++) {
1147 dprintk(1,
1148 KERN_DEBUG
1149 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
1150 I2C_NAME(client), i, saa7114_read(client, i),
1151 decoder->reg[REG_ADDR(i)]);
1154 i = i2c_attach_client(client);
1155 if (i) {
1156 kfree(client);
1157 kfree(decoder);
1158 return i;
1161 //i = saa7114_write_block(client, init, sizeof(init));
1162 i = 0;
1163 if (i < 0) {
1164 dprintk(1, KERN_ERR "%s_attach error: init status %d\n",
1165 I2C_NAME(client), i);
1166 } else {
1167 dprintk(1,
1168 KERN_INFO
1169 "%s_attach: chip version %x at address 0x%x\n",
1170 I2C_NAME(client), saa7114_read(client, 0x00) >> 4,
1171 client->addr << 1);
1174 return 0;
1177 static int
1178 saa7114_attach_adapter (struct i2c_adapter *adapter)
1180 dprintk(1,
1181 KERN_INFO
1182 "saa7114.c: starting probe for adapter %s (0x%x)\n",
1183 I2C_NAME(adapter), adapter->id);
1184 return i2c_probe(adapter, &addr_data, &saa7114_detect_client);
1187 static int
1188 saa7114_detach_client (struct i2c_client *client)
1190 struct saa7114 *decoder = i2c_get_clientdata(client);
1191 int err;
1193 err = i2c_detach_client(client);
1194 if (err) {
1195 return err;
1198 kfree(decoder);
1199 kfree(client);
1201 return 0;
1204 /* ----------------------------------------------------------------------- */
1206 static struct i2c_driver i2c_driver_saa7114 = {
1207 .owner = THIS_MODULE,
1208 .name = "saa7114",
1210 .id = I2C_DRIVERID_SAA7114,
1211 .flags = I2C_DF_NOTIFY,
1213 .attach_adapter = saa7114_attach_adapter,
1214 .detach_client = saa7114_detach_client,
1215 .command = saa7114_command,
1218 static int __init
1219 saa7114_init (void)
1221 return i2c_add_driver(&i2c_driver_saa7114);
1224 static void __exit
1225 saa7114_exit (void)
1227 i2c_del_driver(&i2c_driver_saa7114);
1230 module_init(saa7114_init);
1231 module_exit(saa7114_exit);