[PATCH] I2C: Remove .owner setting from i2c_driver as it's no longer needed
[deliverable/linux.git] / drivers / media / video / saa7114.c
CommitLineData
1da177e4
LT
1/*
2 * saa7114 - Philips SAA7114H video decoder driver version 0.0.1
3 *
4 * Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com>
5 *
6 * Based on saa7111 driver by Dave Perks
7 *
8 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
9 *
10 * Slight changes for video timing and attachment output by
11 * Wolfgang Scherr <scherr@net4you.net>
12 *
13 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
14 * - moved over to linux>=2.4.x i2c protocol (1/1/2003)
15 *
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.
20 *
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.
25 *
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.
29 */
30
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
39#include <linux/slab.h>
40
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>
1da177e4
LT
48#include <linux/types.h>
49
50#include <linux/videodev.h>
51#include <asm/uaccess.h>
52
53MODULE_DESCRIPTION("Philips SAA7114H video decoder driver");
54MODULE_AUTHOR("Maxim Yevtyushkin");
55MODULE_LICENSE("GPL");
56
57#include <linux/i2c.h>
58#include <linux/i2c-dev.h>
59
60#define I2C_NAME(x) (x)->name
61
62#include <linux/video_decoder.h>
63
64static int debug = 0;
65module_param(debug, int, 0);
66MODULE_PARM_DESC(debug, "Debug level (0-1)");
67
68#define dprintk(num, format, args...) \
69 do { \
70 if (debug >= num) \
71 printk(format, ##args); \
72 } while (0)
73
74/* ----------------------------------------------------------------------- */
75
76struct saa7114 {
77 unsigned char reg[0xf0 * 2];
78
79 int norm;
80 int input;
81 int enable;
82 int bright;
83 int contrast;
84 int hue;
85 int sat;
86 int playback;
87};
88
89#define I2C_SAA7114 0x42
90#define I2C_SAA7114A 0x40
91
92#define I2C_DELAY 10
93
94
95//#define SAA_7114_NTSC_HSYNC_START (-3)
96//#define SAA_7114_NTSC_HSYNC_STOP (-18)
97
98#define SAA_7114_NTSC_HSYNC_START (-17)
99#define SAA_7114_NTSC_HSYNC_STOP (-32)
100
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)
106
107#define SAA_7114_SECAM_HSYNC_START (-17)
108#define SAA_7114_SECAM_HSYNC_STOP (-32)
109
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)
114
115#define SAA_7114_PAL_HSYNC_START (-17)
116#define SAA_7114_PAL_HSYNC_STOP (-32)
117
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)
122
123
124
125#define SAA_7114_VERTICAL_CHROMA_OFFSET 0 //0x50504040
126#define SAA_7114_VERTICAL_LUMA_OFFSET 0
127
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))
133
134
135/* ----------------------------------------------------------------------- */
136
137static inline int
138saa7114_write (struct i2c_client *client,
139 u8 reg,
140 u8 value)
141{
142 /*struct saa7114 *decoder = i2c_get_clientdata(client);*/
143
144 /*decoder->reg[reg] = value;*/
145 return i2c_smbus_write_byte_data(client, reg, value);
146}
147
148static int
149saa7114_write_block (struct i2c_client *client,
150 const u8 *data,
151 unsigned int len)
152{
153 int ret = -1;
154 u8 reg;
155
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];
163
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;
180 }
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;
189 }
190 }
191
192 return ret;
193}
194
195static inline int
196saa7114_read (struct i2c_client *client,
197 u8 reg)
198{
199 return i2c_smbus_read_byte_data(client, reg);
200}
201
202/* ----------------------------------------------------------------------- */
203
204// initially set NTSC, composite
205
206
207static 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
465};
466
467static int
468saa7114_command (struct i2c_client *client,
469 unsigned int cmd,
470 void *arg)
471{
472 struct saa7114 *decoder = i2c_get_clientdata(client);
473
474 switch (cmd) {
475
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;
480
481 case DECODER_DUMP:
482 {
483 int i;
484
485 dprintk(1, KERN_INFO "%s: decoder dump\n", I2C_NAME(client));
486
487 for (i = 0; i < 32; i += 16) {
488 int j;
489
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));
494 }
495 printk("\n");
496 }
497 }
498 break;
499
500 case DECODER_GET_CAPABILITIES:
501 {
502 struct video_decoder_capability *cap = arg;
503
504 dprintk(1, KERN_DEBUG "%s: decoder get capabilities\n",
505 I2C_NAME(client));
506
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;
513 }
514 break;
515
516 case DECODER_GET_STATUS:
517 {
518 int *iarg = arg;
519 int status;
520 int res;
521
522 status = saa7114_read(client, 0x1f);
523
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;
529 }
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;
546 }
547 break;
548 }
549 if ((status & (1 << 0)) != 0) {
550 res |= DECODER_STATUS_COLOR;
551 }
552 *iarg = res;
553 }
554 break;
555
556 case DECODER_SET_NORM:
557 {
558 int *iarg = arg;
559
560 short int hoff = 0, voff = 0, w = 0, h = 0;
561
562 dprintk(1, KERN_DEBUG "%s: decoder set norm ",
563 I2C_NAME(client));
564 switch (*iarg) {
565
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;
572
573 decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8; // PLL free when playback, PLL close when capture
574
575 decoder->reg[REG_ADDR(0x0e)] = 0x85;
576 decoder->reg[REG_ADDR(0x0f)] = 0x24;
577
578 hoff = SAA_7114_NTSC_HOFFSET;
579 voff = SAA_7114_NTSC_VOFFSET;
580 w = SAA_7114_NTSC_WIDTH;
581 h = SAA_7114_NTSC_HEIGHT;
582
583 break;
584
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;
591
592 decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8; // PLL free when playback, PLL close when capture
593
594 decoder->reg[REG_ADDR(0x0e)] = 0x81;
595 decoder->reg[REG_ADDR(0x0f)] = 0x24;
596
597 hoff = SAA_7114_PAL_HOFFSET;
598 voff = SAA_7114_PAL_VOFFSET;
599 w = SAA_7114_PAL_WIDTH;
600 h = SAA_7114_PAL_HEIGHT;
601
602 break;
603
604 default:
605 dprintk(1, " Unknown video mode!!!\n");
606 return -EINVAL;
607
608 }
609
610
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
623
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
636
637
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
641
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);
648
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);
653
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
657
658 decoder->norm = *iarg;
659 }
660 break;
661
662 case DECODER_SET_INPUT:
663 {
664 int *iarg = arg;
665
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;
670 }
671
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;
677
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)]);
686
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)]);
696
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)]);
704 }
705 }
706 break;
707
708 case DECODER_SET_OUTPUT:
709 {
710 int *iarg = arg;
711
712 dprintk(1, KERN_DEBUG "%s: decoder set output\n",
713 I2C_NAME(client));
714
715 /* not much choice of outputs */
716 if (*iarg != 0) {
717 return -EINVAL;
718 }
719 }
720 break;
721
722 case DECODER_ENABLE_OUTPUT:
723 {
724 int *iarg = arg;
725 int enable = (*iarg != 0);
726
727 dprintk(1, KERN_DEBUG "%s: decoder %s output\n",
728 I2C_NAME(client), enable ? "enable" : "disable");
729
730 decoder->playback = !enable;
731
732 if (decoder->enable != enable) {
733 decoder->enable = enable;
734
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.
740 *
741 * If output should be enabled, we have to
742 * reverse the above.
743 */
744
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;
755 }
756
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);
767
768 }
769 }
770 break;
771
772 case DECODER_SET_PICTURE:
773 {
774 struct video_picture *pic = arg;
775
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);
781
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);
786 }
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);
792 }
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);
797 }
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);
803 }
804 }
805 break;
806
807 default:
808 return -EINVAL;
809 }
810
811 return 0;
812}
813
814/* ----------------------------------------------------------------------- */
815
816/*
817 * Generic i2c probe
818 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
819 */
820static unsigned short normal_i2c[] =
821 { I2C_SAA7114 >> 1, I2C_SAA7114A >> 1, I2C_CLIENT_END };
1da177e4 822
68cc9d0b 823static unsigned short ignore = I2C_CLIENT_END;
1da177e4
LT
824
825static struct i2c_client_address_data addr_data = {
826 .normal_i2c = normal_i2c,
68cc9d0b
JD
827 .probe = &ignore,
828 .ignore = &ignore,
1da177e4
LT
829};
830
831static struct i2c_driver i2c_driver_saa7114;
832
833static int
834saa7114_detect_client (struct i2c_adapter *adapter,
835 int address,
836 int kind)
837{
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;
845
846 dprintk(1,
847 KERN_INFO
848 "saa7114.c: detecting saa7114 client on address 0x%x\n",
849 address << 1);
850
851 /* Check if the adapter supports the needed features */
852 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
853 return 0;
854
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;
1da177e4
LT
862 strlcpy(I2C_NAME(client), "saa7114", sizeof(I2C_NAME(client)));
863
864 decoder = kmalloc(sizeof(struct saa7114), GFP_KERNEL);
865 if (decoder == NULL) {
866 kfree(client);
867 return -ENOMEM;
868 }
869 memset(decoder, 0, sizeof(struct saa7114));
870 decoder->norm = VIDEO_MODE_NTSC;
871 decoder->input = -1;
872 decoder->enable = 1;
873 decoder->bright = 32768;
874 decoder->contrast = 32768;
875 decoder->hue = 32768;
876 decoder->sat = 32768;
877 decoder->playback = 0; // initially capture mode useda
878 i2c_set_clientdata(client, decoder);
879
880 memcpy(decoder->reg, init, sizeof(init));
881
882 decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff); // hoffset low
883 decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f; // hoffset high
884 decoder->reg[REG_ADDR(0x96)] = LOBYTE(w); // width low
885 decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f; // width high
886 decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff); // voffset low
887 decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f; // voffset high
888 decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2); // height low
889 decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f; // height high
890 decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w); // out width low
891 decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f; // out width high
892 decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h); // out height low
893 decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f; // out height high
894
895 decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff); // hoffset low
896 decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f; // hoffset high
897 decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w); // width low
898 decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f; // width high
899 decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff); // voffset low
900 decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f; // voffset high
901 decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2); // height low
902 decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f; // height high
903 decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w); // out width low
904 decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f; // out width high
905 decoder->reg[REG_ADDR(0xce)] = LOBYTE(h); // out height low
906 decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f; // out height high
907
908 decoder->reg[REG_ADDR(0xb8)] =
909 LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
910 decoder->reg[REG_ADDR(0xb9)] =
911 HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
912 decoder->reg[REG_ADDR(0xba)] =
913 LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
914 decoder->reg[REG_ADDR(0xbb)] =
915 HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
916
917 decoder->reg[REG_ADDR(0xbc)] =
918 LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
919 decoder->reg[REG_ADDR(0xbd)] =
920 HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
921 decoder->reg[REG_ADDR(0xbe)] =
922 LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
923 decoder->reg[REG_ADDR(0xbf)] =
924 HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
925
926 decoder->reg[REG_ADDR(0xe8)] =
927 LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
928 decoder->reg[REG_ADDR(0xe9)] =
929 HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
930 decoder->reg[REG_ADDR(0xea)] =
931 LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
932 decoder->reg[REG_ADDR(0xeb)] =
933 HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
934
935 decoder->reg[REG_ADDR(0xec)] =
936 LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
937 decoder->reg[REG_ADDR(0xed)] =
938 HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
939 decoder->reg[REG_ADDR(0xee)] =
940 LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
941 decoder->reg[REG_ADDR(0xef)] =
942 HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
943
944
945 decoder->reg[REG_ADDR(0x13)] = 0x80; // RTC0 on
946 decoder->reg[REG_ADDR(0x87)] = 0x01; // I-Port
947 decoder->reg[REG_ADDR(0x12)] = 0xc9; // RTS0
948
949 decoder->reg[REG_ADDR(0x02)] = 0xc0; // set composite1 input, aveasy
950 decoder->reg[REG_ADDR(0x09)] = 0x00; // chrominance trap
951 decoder->reg[REG_ADDR(0x0e)] |= 1; // combfilter on
952
953
954 dprintk(1, KERN_DEBUG "%s_attach: starting decoder init\n",
955 I2C_NAME(client));
956
957 err[0] =
958 saa7114_write_block(client, decoder->reg + (0x20 << 1),
959 0x10 << 1);
960 err[1] =
961 saa7114_write_block(client, decoder->reg + (0x30 << 1),
962 0x10 << 1);
963 err[2] =
964 saa7114_write_block(client, decoder->reg + (0x63 << 1),
965 (0x7f + 1 - 0x63) << 1);
966 err[3] =
967 saa7114_write_block(client, decoder->reg + (0x89 << 1),
968 6 << 1);
969 err[4] =
970 saa7114_write_block(client, decoder->reg + (0xb8 << 1),
971 8 << 1);
972 err[5] =
973 saa7114_write_block(client, decoder->reg + (0xe8 << 1),
974 8 << 1);
975
976
977 for (i = 0; i <= 5; i++) {
978 if (err[i] < 0) {
979 dprintk(1,
980 KERN_ERR
981 "%s_attach: init error %d at stage %d, leaving attach.\n",
982 I2C_NAME(client), i, err[i]);
983 kfree(decoder);
984 kfree(client);
985 return 0;
986 }
987 }
988
989 for (i = 6; i < 8; i++) {
990 dprintk(1,
991 KERN_DEBUG
992 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
993 I2C_NAME(client), i, saa7114_read(client, i),
994 decoder->reg[REG_ADDR(i)]);
995 }
996
997 dprintk(1,
998 KERN_DEBUG
999 "%s_attach: performing decoder reset sequence\n",
1000 I2C_NAME(client));
1001
1002 err[6] = saa7114_write(client, 0x80, 0x06); // i-port and scaler backend clock selection, task A&B off
1003 err[7] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler
1004 err[8] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
1005
1006 for (i = 6; i <= 8; i++) {
1007 if (err[i] < 0) {
1008 dprintk(1,
1009 KERN_ERR
1010 "%s_attach: init error %d at stage %d, leaving attach.\n",
1011 I2C_NAME(client), i, err[i]);
1012 kfree(decoder);
1013 kfree(client);
1014 return 0;
1015 }
1016 }
1017
1018 dprintk(1, KERN_INFO "%s_attach: performing the rest of init\n",
1019 I2C_NAME(client));
1020
1021
1022 err[9] = saa7114_write(client, 0x01, decoder->reg[REG_ADDR(0x01)]);
1023 err[10] = saa7114_write_block(client, decoder->reg + (0x03 << 1), (0x1e + 1 - 0x03) << 1); // big seq
1024 err[11] = saa7114_write_block(client, decoder->reg + (0x40 << 1), (0x5f + 1 - 0x40) << 1); // slicer
1025 err[12] = saa7114_write_block(client, decoder->reg + (0x81 << 1), 2 << 1); // ?
1026 err[13] = saa7114_write_block(client, decoder->reg + (0x83 << 1), 5 << 1); // ?
1027 err[14] = saa7114_write_block(client, decoder->reg + (0x90 << 1), 4 << 1); // Task A
1028 err[15] =
1029 saa7114_write_block(client, decoder->reg + (0x94 << 1),
1030 12 << 1);
1031 err[16] =
1032 saa7114_write_block(client, decoder->reg + (0xa0 << 1),
1033 8 << 1);
1034 err[17] =
1035 saa7114_write_block(client, decoder->reg + (0xa8 << 1),
1036 8 << 1);
1037 err[18] =
1038 saa7114_write_block(client, decoder->reg + (0xb0 << 1),
1039 8 << 1);
1040 err[19] = saa7114_write_block(client, decoder->reg + (0xc0 << 1), 4 << 1); // Task B
1041 err[15] =
1042 saa7114_write_block(client, decoder->reg + (0xc4 << 1),
1043 12 << 1);
1044 err[16] =
1045 saa7114_write_block(client, decoder->reg + (0xd0 << 1),
1046 8 << 1);
1047 err[17] =
1048 saa7114_write_block(client, decoder->reg + (0xd8 << 1),
1049 8 << 1);
1050 err[18] =
1051 saa7114_write_block(client, decoder->reg + (0xe0 << 1),
1052 8 << 1);
1053
1054 for (i = 9; i <= 18; i++) {
1055 if (err[i] < 0) {
1056 dprintk(1,
1057 KERN_ERR
1058 "%s_attach: init error %d at stage %d, leaving attach.\n",
1059 I2C_NAME(client), i, err[i]);
1060 kfree(decoder);
1061 kfree(client);
1062 return 0;
1063 }
1064 }
1065
1066
1067 for (i = 6; i < 8; i++) {
1068 dprintk(1,
1069 KERN_DEBUG
1070 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
1071 I2C_NAME(client), i, saa7114_read(client, i),
1072 decoder->reg[REG_ADDR(i)]);
1073 }
1074
1075
1076 for (i = 0x11; i <= 0x13; i++) {
1077 dprintk(1,
1078 KERN_DEBUG
1079 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
1080 I2C_NAME(client), i, saa7114_read(client, i),
1081 decoder->reg[REG_ADDR(i)]);
1082 }
1083
1084
1085 dprintk(1, KERN_DEBUG "%s_attach: setting video input\n",
1086 I2C_NAME(client));
1087
1088 err[19] =
1089 saa7114_write(client, 0x02, decoder->reg[REG_ADDR(0x02)]);
1090 err[20] =
1091 saa7114_write(client, 0x09, decoder->reg[REG_ADDR(0x09)]);
1092 err[21] =
1093 saa7114_write(client, 0x0e, decoder->reg[REG_ADDR(0x0e)]);
1094
1095 for (i = 19; i <= 21; i++) {
1096 if (err[i] < 0) {
1097 dprintk(1,
1098 KERN_ERR
1099 "%s_attach: init error %d at stage %d, leaving attach.\n",
1100 I2C_NAME(client), i, err[i]);
1101 kfree(decoder);
1102 kfree(client);
1103 return 0;
1104 }
1105 }
1106
1107 dprintk(1,
1108 KERN_DEBUG
1109 "%s_attach: performing decoder reset sequence\n",
1110 I2C_NAME(client));
1111
1112 err[22] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler
1113 err[23] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
1114 err[24] = saa7114_write(client, 0x80, 0x36); // i-port and scaler backend clock selection, task A&B off
1115
1116
1117 for (i = 22; i <= 24; i++) {
1118 if (err[i] < 0) {
1119 dprintk(1,
1120 KERN_ERR
1121 "%s_attach: init error %d at stage %d, leaving attach.\n",
1122 I2C_NAME(client), i, err[i]);
1123 kfree(decoder);
1124 kfree(client);
1125 return 0;
1126 }
1127 }
1128
1129 err[25] = saa7114_write(client, 0x06, init[REG_ADDR(0x06)]);
1130 err[26] = saa7114_write(client, 0x07, init[REG_ADDR(0x07)]);
1131 err[27] = saa7114_write(client, 0x10, init[REG_ADDR(0x10)]);
1132
1133 dprintk(1,
1134 KERN_INFO
1135 "%s_attach: chip version %x, decoder status 0x%02x\n",
1136 I2C_NAME(client), saa7114_read(client, 0x00) >> 4,
1137 saa7114_read(client, 0x1f));
1138 dprintk(1,
1139 KERN_DEBUG
1140 "%s_attach: power save control: 0x%02x, scaler status: 0x%02x\n",
1141 I2C_NAME(client), saa7114_read(client, 0x88),
1142 saa7114_read(client, 0x8f));
1143
1144
1145 for (i = 0x94; i < 0x96; i++) {
1146 dprintk(1,
1147 KERN_DEBUG
1148 "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
1149 I2C_NAME(client), i, saa7114_read(client, i),
1150 decoder->reg[REG_ADDR(i)]);
1151 }
1152
1153 i = i2c_attach_client(client);
1154 if (i) {
1155 kfree(client);
1156 kfree(decoder);
1157 return i;
1158 }
1159
1160 //i = saa7114_write_block(client, init, sizeof(init));
1161 i = 0;
1162 if (i < 0) {
1163 dprintk(1, KERN_ERR "%s_attach error: init status %d\n",
1164 I2C_NAME(client), i);
1165 } else {
1166 dprintk(1,
1167 KERN_INFO
1168 "%s_attach: chip version %x at address 0x%x\n",
1169 I2C_NAME(client), saa7114_read(client, 0x00) >> 4,
1170 client->addr << 1);
1171 }
1172
1173 return 0;
1174}
1175
1176static int
1177saa7114_attach_adapter (struct i2c_adapter *adapter)
1178{
1179 dprintk(1,
1180 KERN_INFO
1181 "saa7114.c: starting probe for adapter %s (0x%x)\n",
1182 I2C_NAME(adapter), adapter->id);
1183 return i2c_probe(adapter, &addr_data, &saa7114_detect_client);
1184}
1185
1186static int
1187saa7114_detach_client (struct i2c_client *client)
1188{
1189 struct saa7114 *decoder = i2c_get_clientdata(client);
1190 int err;
1191
1192 err = i2c_detach_client(client);
1193 if (err) {
1194 return err;
1195 }
1196
1197 kfree(decoder);
1198 kfree(client);
1199
1200 return 0;
1201}
1202
1203/* ----------------------------------------------------------------------- */
1204
1205static struct i2c_driver i2c_driver_saa7114 = {
604f28e2 1206 .driver = {
604f28e2
LR
1207 .name = "saa7114",
1208 },
1da177e4
LT
1209
1210 .id = I2C_DRIVERID_SAA7114,
1da177e4
LT
1211
1212 .attach_adapter = saa7114_attach_adapter,
1213 .detach_client = saa7114_detach_client,
1214 .command = saa7114_command,
1215};
1216
1217static int __init
1218saa7114_init (void)
1219{
1220 return i2c_add_driver(&i2c_driver_saa7114);
1221}
1222
1223static void __exit
1224saa7114_exit (void)
1225{
1226 i2c_del_driver(&i2c_driver_saa7114);
1227}
1228
1229module_init(saa7114_init);
1230module_exit(saa7114_exit);
This page took 0.142581 seconds and 5 git commands to generate.