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