linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / media / video / saa7127.c
1 /*
2  * saa7127 - Philips SAA7127/SAA7129 video encoder driver
3  *
4  * Copyright (C) 2003 Roy Bulter <rbulter@hetnet.nl>
5  *
6  * Based on SAA7126 video encoder driver by Gillem & Andreas Oberritter
7  *
8  * Copyright (C) 2000-2001 Gillem <htoa@gmx.net>
9  * Copyright (C) 2002 Andreas Oberritter <obi@saftware.de>
10  *
11  * Based on Stadis 4:2:2 MPEG-2 Decoder Driver by Nathan Laredo
12  *
13  * Copyright (C) 1999 Nathan Laredo <laredo@gnu.org>
14  *
15  * This driver is designed for the Hauppauge 250/350 Linux driver
16  * from the ivtv Project
17  *
18  * Copyright (C) 2003 Kevin Thayer <nufan_wfk@yahoo.com>
19  *
20  * Dual output support:
21  * Copyright (C) 2004 Eric Varsanyi
22  *
23  * NTSC Tuning and 7.5 IRE Setup
24  * Copyright (C) 2004  Chris Kennedy <c@groovy.org>
25  *
26  * VBI additions & cleanup:
27  * Copyright (C) 2004, 2005 Hans Verkuil <hverkuil@xs4all.nl>
28  *
29  * Note: the saa7126 is identical to the saa7127, and the saa7128 is
30  * identical to the saa7129, except that the saa7126 and saa7128 have
31  * macrovision anti-taping support. This driver will almost certainly
32  * work find for those chips, except of course for the missing anti-taping
33  * support.
34  *
35  * This program is free software; you can redistribute it and/or modify
36  * it under the terms of the GNU General Public License as published by
37  * the Free Software Foundation; either version 2 of the License, or
38  * (at your option) any later version.
39  *
40  * This program is distributed in the hope that it will be useful,
41  * but WITHOUT ANY WARRANTY; without even the implied warranty of
42  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
43  * GNU General Public License for more details.
44  *
45  * You should have received a copy of the GNU General Public License
46  * along with this program; if not, write to the Free Software
47  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
48  */
49
50
51 #include <linux/kernel.h>
52 #include <linux/module.h>
53 #include <linux/slab.h>
54 #include <linux/i2c.h>
55 #include <linux/videodev2.h>
56 #include <media/v4l2-common.h>
57
58 static int debug = 0;
59 static int test_image = 0;
60
61 MODULE_DESCRIPTION("Philips SAA7127/9 video encoder driver");
62 MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil");
63 MODULE_LICENSE("GPL");
64 module_param(debug, int, 0644);
65 module_param(test_image, int, 0644);
66 MODULE_PARM_DESC(debug, "debug level (0-2)");
67 MODULE_PARM_DESC(test_image, "test_image (0-1)");
68
69 static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
70
71
72 I2C_CLIENT_INSMOD;
73
74 /*
75  * SAA7127 registers
76  */
77
78 #define SAA7127_REG_STATUS                           0x00
79 #define SAA7127_REG_WIDESCREEN_CONFIG                0x26
80 #define SAA7127_REG_WIDESCREEN_ENABLE                0x27
81 #define SAA7127_REG_BURST_START                      0x28
82 #define SAA7127_REG_BURST_END                        0x29
83 #define SAA7127_REG_COPYGEN_0                        0x2a
84 #define SAA7127_REG_COPYGEN_1                        0x2b
85 #define SAA7127_REG_COPYGEN_2                        0x2c
86 #define SAA7127_REG_OUTPUT_PORT_CONTROL              0x2d
87 #define SAA7127_REG_GAIN_LUMINANCE_RGB               0x38
88 #define SAA7127_REG_GAIN_COLORDIFF_RGB               0x39
89 #define SAA7127_REG_INPUT_PORT_CONTROL_1             0x3a
90 #define SAA7129_REG_FADE_KEY_COL2                    0x4f
91 #define SAA7127_REG_CHROMA_PHASE                     0x5a
92 #define SAA7127_REG_GAINU                            0x5b
93 #define SAA7127_REG_GAINV                            0x5c
94 #define SAA7127_REG_BLACK_LEVEL                      0x5d
95 #define SAA7127_REG_BLANKING_LEVEL                   0x5e
96 #define SAA7127_REG_VBI_BLANKING                     0x5f
97 #define SAA7127_REG_DAC_CONTROL                      0x61
98 #define SAA7127_REG_BURST_AMP                        0x62
99 #define SAA7127_REG_SUBC3                            0x63
100 #define SAA7127_REG_SUBC2                            0x64
101 #define SAA7127_REG_SUBC1                            0x65
102 #define SAA7127_REG_SUBC0                            0x66
103 #define SAA7127_REG_LINE_21_ODD_0                    0x67
104 #define SAA7127_REG_LINE_21_ODD_1                    0x68
105 #define SAA7127_REG_LINE_21_EVEN_0                   0x69
106 #define SAA7127_REG_LINE_21_EVEN_1                   0x6a
107 #define SAA7127_REG_RCV_PORT_CONTROL                 0x6b
108 #define SAA7127_REG_VTRIG                            0x6c
109 #define SAA7127_REG_HTRIG_HI                         0x6d
110 #define SAA7127_REG_MULTI                            0x6e
111 #define SAA7127_REG_CLOSED_CAPTION                   0x6f
112 #define SAA7127_REG_RCV2_OUTPUT_START                0x70
113 #define SAA7127_REG_RCV2_OUTPUT_END                  0x71
114 #define SAA7127_REG_RCV2_OUTPUT_MSBS                 0x72
115 #define SAA7127_REG_TTX_REQUEST_H_START              0x73
116 #define SAA7127_REG_TTX_REQUEST_H_DELAY_LENGTH       0x74
117 #define SAA7127_REG_CSYNC_ADVANCE_VSYNC_SHIFT        0x75
118 #define SAA7127_REG_TTX_ODD_REQ_VERT_START           0x76
119 #define SAA7127_REG_TTX_ODD_REQ_VERT_END             0x77
120 #define SAA7127_REG_TTX_EVEN_REQ_VERT_START          0x78
121 #define SAA7127_REG_TTX_EVEN_REQ_VERT_END            0x79
122 #define SAA7127_REG_FIRST_ACTIVE                     0x7a
123 #define SAA7127_REG_LAST_ACTIVE                      0x7b
124 #define SAA7127_REG_MSB_VERTICAL                     0x7c
125 #define SAA7127_REG_DISABLE_TTX_LINE_LO_0            0x7e
126 #define SAA7127_REG_DISABLE_TTX_LINE_LO_1            0x7f
127
128 /*
129  **********************************************************************
130  *
131  *  Arrays with configuration parameters for the SAA7127
132  *
133  **********************************************************************
134  */
135
136 struct i2c_reg_value {
137         unsigned char reg;
138         unsigned char value;
139 };
140
141 static const struct i2c_reg_value saa7129_init_config_extra[] = {
142         { SAA7127_REG_OUTPUT_PORT_CONTROL,              0x38 },
143         { SAA7127_REG_VTRIG,                            0xfa },
144         { 0, 0 }
145 };
146
147 static const struct i2c_reg_value saa7127_init_config_common[] = {
148         { SAA7127_REG_WIDESCREEN_CONFIG,                0x0d },
149         { SAA7127_REG_WIDESCREEN_ENABLE,                0x00 },
150         { SAA7127_REG_COPYGEN_0,                        0x77 },
151         { SAA7127_REG_COPYGEN_1,                        0x41 },
152         { SAA7127_REG_COPYGEN_2,                        0x00 }, /* Macrovision enable/disable */
153         { SAA7127_REG_OUTPUT_PORT_CONTROL,              0x9e },
154         { SAA7127_REG_GAIN_LUMINANCE_RGB,               0x00 },
155         { SAA7127_REG_GAIN_COLORDIFF_RGB,               0x00 },
156         { SAA7127_REG_INPUT_PORT_CONTROL_1,             0x80 }, /* for color bars */
157         { SAA7127_REG_LINE_21_ODD_0,                    0x77 },
158         { SAA7127_REG_LINE_21_ODD_1,                    0x41 },
159         { SAA7127_REG_LINE_21_EVEN_0,                   0x88 },
160         { SAA7127_REG_LINE_21_EVEN_1,                   0x41 },
161         { SAA7127_REG_RCV_PORT_CONTROL,                 0x12 },
162         { SAA7127_REG_VTRIG,                            0xf9 },
163         { SAA7127_REG_HTRIG_HI,                         0x00 },
164         { SAA7127_REG_RCV2_OUTPUT_START,                0x41 },
165         { SAA7127_REG_RCV2_OUTPUT_END,                  0xc3 },
166         { SAA7127_REG_RCV2_OUTPUT_MSBS,                 0x00 },
167         { SAA7127_REG_TTX_REQUEST_H_START,              0x3e },
168         { SAA7127_REG_TTX_REQUEST_H_DELAY_LENGTH,       0xb8 },
169         { SAA7127_REG_CSYNC_ADVANCE_VSYNC_SHIFT,        0x03 },
170         { SAA7127_REG_TTX_ODD_REQ_VERT_START,           0x15 },
171         { SAA7127_REG_TTX_ODD_REQ_VERT_END,             0x16 },
172         { SAA7127_REG_TTX_EVEN_REQ_VERT_START,          0x15 },
173         { SAA7127_REG_TTX_EVEN_REQ_VERT_END,            0x16 },
174         { SAA7127_REG_FIRST_ACTIVE,                     0x1a },
175         { SAA7127_REG_LAST_ACTIVE,                      0x01 },
176         { SAA7127_REG_MSB_VERTICAL,                     0xc0 },
177         { SAA7127_REG_DISABLE_TTX_LINE_LO_0,            0x00 },
178         { SAA7127_REG_DISABLE_TTX_LINE_LO_1,            0x00 },
179         { 0, 0 }
180 };
181
182 #define SAA7127_60HZ_DAC_CONTROL 0x15
183 static const struct i2c_reg_value saa7127_init_config_60hz[] = {
184         { SAA7127_REG_BURST_START,                      0x19 },
185         /* BURST_END is also used as a chip ID in saa7127_detect_client */
186         { SAA7127_REG_BURST_END,                        0x1d },
187         { SAA7127_REG_CHROMA_PHASE,                     0xa3 },
188         { SAA7127_REG_GAINU,                            0x98 },
189         { SAA7127_REG_GAINV,                            0xd3 },
190         { SAA7127_REG_BLACK_LEVEL,                      0x39 },
191         { SAA7127_REG_BLANKING_LEVEL,                   0x2e },
192         { SAA7127_REG_VBI_BLANKING,                     0x2e },
193         { SAA7127_REG_DAC_CONTROL,                      0x15 },
194         { SAA7127_REG_BURST_AMP,                        0x4d },
195         { SAA7127_REG_SUBC3,                            0x1f },
196         { SAA7127_REG_SUBC2,                            0x7c },
197         { SAA7127_REG_SUBC1,                            0xf0 },
198         { SAA7127_REG_SUBC0,                            0x21 },
199         { SAA7127_REG_MULTI,                            0x90 },
200         { SAA7127_REG_CLOSED_CAPTION,                   0x11 },
201         { 0, 0 }
202 };
203
204 #define SAA7127_50HZ_DAC_CONTROL 0x02
205 static struct i2c_reg_value saa7127_init_config_50hz[] = {
206         { SAA7127_REG_BURST_START,                      0x21 },
207         /* BURST_END is also used as a chip ID in saa7127_detect_client */
208         { SAA7127_REG_BURST_END,                        0x1d },
209         { SAA7127_REG_CHROMA_PHASE,                     0x3f },
210         { SAA7127_REG_GAINU,                            0x7d },
211         { SAA7127_REG_GAINV,                            0xaf },
212         { SAA7127_REG_BLACK_LEVEL,                      0x33 },
213         { SAA7127_REG_BLANKING_LEVEL,                   0x35 },
214         { SAA7127_REG_VBI_BLANKING,                     0x35 },
215         { SAA7127_REG_DAC_CONTROL,                      0x02 },
216         { SAA7127_REG_BURST_AMP,                        0x2f },
217         { SAA7127_REG_SUBC3,                            0xcb },
218         { SAA7127_REG_SUBC2,                            0x8a },
219         { SAA7127_REG_SUBC1,                            0x09 },
220         { SAA7127_REG_SUBC0,                            0x2a },
221         { SAA7127_REG_MULTI,                            0xa0 },
222         { SAA7127_REG_CLOSED_CAPTION,                   0x00 },
223         { 0, 0 }
224 };
225
226 /* Enumeration for the Supported input types */
227 enum saa7127_input_type {
228         SAA7127_INPUT_TYPE_NORMAL,
229         SAA7127_INPUT_TYPE_TEST_IMAGE
230 };
231
232 /* Enumeration for the Supported Output signal types */
233 enum saa7127_output_type {
234         SAA7127_OUTPUT_TYPE_BOTH,
235         SAA7127_OUTPUT_TYPE_COMPOSITE,
236         SAA7127_OUTPUT_TYPE_SVIDEO,
237         SAA7127_OUTPUT_TYPE_RGB,
238         SAA7127_OUTPUT_TYPE_YUV_C,
239         SAA7127_OUTPUT_TYPE_YUV_V
240 };
241
242 /*
243  **********************************************************************
244  *
245  *  Encoder Struct, holds the configuration state of the encoder
246  *
247  **********************************************************************
248  */
249
250 struct saa7127_state {
251         v4l2_std_id std;
252         enum v4l2_chip_ident ident;
253         enum saa7127_input_type input_type;
254         enum saa7127_output_type output_type;
255         int video_enable;
256         int wss_enable;
257         u16 wss_mode;
258         int cc_enable;
259         u16 cc_data;
260         int xds_enable;
261         u16 xds_data;
262         int vps_enable;
263         u8 vps_data[5];
264         u8 reg_2d;
265         u8 reg_3a;
266         u8 reg_3a_cb;   /* colorbar bit */
267         u8 reg_61;
268 };
269
270 static const char * const output_strs[] =
271 {
272         "S-Video + Composite",
273         "Composite",
274         "S-Video",
275         "RGB",
276         "YUV C",
277         "YUV V"
278 };
279
280 static const char * const wss_strs[] = {
281         "invalid",
282         "letterbox 14:9 center",
283         "letterbox 14:9 top",
284         "invalid",
285         "letterbox 16:9 top",
286         "invalid",
287         "invalid",
288         "16:9 full format anamorphic"
289         "4:3 full format",
290         "invalid",
291         "invalid",
292         "letterbox 16:9 center",
293         "invalid",
294         "letterbox >16:9 center",
295         "14:9 full format center",
296         "invalid",
297 };
298
299 /* ----------------------------------------------------------------------- */
300
301 static int saa7127_read(struct i2c_client *client, u8 reg)
302 {
303         return i2c_smbus_read_byte_data(client, reg);
304 }
305
306 /* ----------------------------------------------------------------------- */
307
308 static int saa7127_write(struct i2c_client *client, u8 reg, u8 val)
309 {
310         int i;
311
312         for (i = 0; i < 3; i++) {
313                 if (i2c_smbus_write_byte_data(client, reg, val) == 0)
314                         return 0;
315         }
316         v4l_err(client, "I2C Write Problem\n");
317         return -1;
318 }
319
320 /* ----------------------------------------------------------------------- */
321
322 static int saa7127_write_inittab(struct i2c_client *client,
323                                  const struct i2c_reg_value *regs)
324 {
325         while (regs->reg != 0) {
326                 saa7127_write(client, regs->reg, regs->value);
327                 regs++;
328         }
329         return 0;
330 }
331
332 /* ----------------------------------------------------------------------- */
333
334 static int saa7127_set_vps(struct i2c_client *client, struct v4l2_sliced_vbi_data *data)
335 {
336         struct saa7127_state *state = i2c_get_clientdata(client);
337         int enable = (data->line != 0);
338
339         if (enable && (data->field != 0 || data->line != 16))
340                 return -EINVAL;
341         if (state->vps_enable != enable) {
342                 v4l_dbg(1, debug, client, "Turn VPS Signal %s\n", enable ? "on" : "off");
343                 saa7127_write(client, 0x54, enable << 7);
344                 state->vps_enable = enable;
345         }
346         if (!enable)
347                 return 0;
348
349         state->vps_data[0] = data->data[4];
350         state->vps_data[1] = data->data[10];
351         state->vps_data[2] = data->data[11];
352         state->vps_data[3] = data->data[12];
353         state->vps_data[4] = data->data[13];
354         v4l_dbg(1, debug, client, "Set VPS data %02x %02x %02x %02x %02x\n",
355                 state->vps_data[0], state->vps_data[1],
356                 state->vps_data[2], state->vps_data[3],
357                 state->vps_data[4]);
358         saa7127_write(client, 0x55, state->vps_data[0]);
359         saa7127_write(client, 0x56, state->vps_data[1]);
360         saa7127_write(client, 0x57, state->vps_data[2]);
361         saa7127_write(client, 0x58, state->vps_data[3]);
362         saa7127_write(client, 0x59, state->vps_data[4]);
363         return 0;
364 }
365
366 /* ----------------------------------------------------------------------- */
367
368 static int saa7127_set_cc(struct i2c_client *client, struct v4l2_sliced_vbi_data *data)
369 {
370         struct saa7127_state *state = i2c_get_clientdata(client);
371         u16 cc = data->data[1] << 8 | data->data[0];
372         int enable = (data->line != 0);
373
374         if (enable && (data->field != 0 || data->line != 21))
375                 return -EINVAL;
376         if (state->cc_enable != enable) {
377                 v4l_dbg(1, debug, client, "Turn CC %s\n", enable ? "on" : "off");
378                 saa7127_write(client, SAA7127_REG_CLOSED_CAPTION,
379                                 (state->xds_enable << 7) | (enable << 6) | 0x11);
380                 state->cc_enable = enable;
381         }
382         if (!enable)
383                 return 0;
384
385         v4l_dbg(2, debug, client, "CC data: %04x\n", cc);
386         saa7127_write(client, SAA7127_REG_LINE_21_ODD_0, cc & 0xff);
387         saa7127_write(client, SAA7127_REG_LINE_21_ODD_1, cc >> 8);
388         state->cc_data = cc;
389         return 0;
390 }
391
392 /* ----------------------------------------------------------------------- */
393
394 static int saa7127_set_xds(struct i2c_client *client, struct v4l2_sliced_vbi_data *data)
395 {
396         struct saa7127_state *state = i2c_get_clientdata(client);
397         u16 xds = data->data[1] << 8 | data->data[0];
398         int enable = (data->line != 0);
399
400         if (enable && (data->field != 1 || data->line != 21))
401                 return -EINVAL;
402         if (state->xds_enable != enable) {
403                 v4l_dbg(1, debug, client, "Turn XDS %s\n", enable ? "on" : "off");
404                 saa7127_write(client, SAA7127_REG_CLOSED_CAPTION,
405                                 (enable << 7) | (state->cc_enable << 6) | 0x11);
406                 state->xds_enable = enable;
407         }
408         if (!enable)
409                 return 0;
410
411         v4l_dbg(2, debug, client, "XDS data: %04x\n", xds);
412         saa7127_write(client, SAA7127_REG_LINE_21_EVEN_0, xds & 0xff);
413         saa7127_write(client, SAA7127_REG_LINE_21_EVEN_1, xds >> 8);
414         state->xds_data = xds;
415         return 0;
416 }
417
418 /* ----------------------------------------------------------------------- */
419
420 static int saa7127_set_wss(struct i2c_client *client, struct v4l2_sliced_vbi_data *data)
421 {
422         struct saa7127_state *state = i2c_get_clientdata(client);
423         int enable = (data->line != 0);
424
425         if (enable && (data->field != 0 || data->line != 23))
426                 return -EINVAL;
427         if (state->wss_enable != enable) {
428                 v4l_dbg(1, debug, client, "Turn WSS %s\n", enable ? "on" : "off");
429                 saa7127_write(client, 0x27, enable << 7);
430                 state->wss_enable = enable;
431         }
432         if (!enable)
433                 return 0;
434
435         saa7127_write(client, 0x26, data->data[0]);
436         saa7127_write(client, 0x27, 0x80 | (data->data[1] & 0x3f));
437         v4l_dbg(1, debug, client, "WSS mode: %s\n", wss_strs[data->data[0] & 0xf]);
438         state->wss_mode = (data->data[1] & 0x3f) << 8 | data->data[0];
439         return 0;
440 }
441
442 /* ----------------------------------------------------------------------- */
443
444 static int saa7127_set_video_enable(struct i2c_client *client, int enable)
445 {
446         struct saa7127_state *state = i2c_get_clientdata(client);
447
448         if (enable) {
449                 v4l_dbg(1, debug, client, "Enable Video Output\n");
450                 saa7127_write(client, 0x2d, state->reg_2d);
451                 saa7127_write(client, 0x61, state->reg_61);
452         } else {
453                 v4l_dbg(1, debug, client, "Disable Video Output\n");
454                 saa7127_write(client, 0x2d, (state->reg_2d & 0xf0));
455                 saa7127_write(client, 0x61, (state->reg_61 | 0xc0));
456         }
457         state->video_enable = enable;
458         return 0;
459 }
460
461 /* ----------------------------------------------------------------------- */
462
463 static int saa7127_set_std(struct i2c_client *client, v4l2_std_id std)
464 {
465         struct saa7127_state *state = i2c_get_clientdata(client);
466         const struct i2c_reg_value *inittab;
467
468         if (std & V4L2_STD_525_60) {
469                 v4l_dbg(1, debug, client, "Selecting 60 Hz video Standard\n");
470                 inittab = saa7127_init_config_60hz;
471                 state->reg_61 = SAA7127_60HZ_DAC_CONTROL;
472         } else {
473                 v4l_dbg(1, debug, client, "Selecting 50 Hz video Standard\n");
474                 inittab = saa7127_init_config_50hz;
475                 state->reg_61 = SAA7127_50HZ_DAC_CONTROL;
476         }
477
478         /* Write Table */
479         saa7127_write_inittab(client, inittab);
480         state->std = std;
481         return 0;
482 }
483
484 /* ----------------------------------------------------------------------- */
485
486 static int saa7127_set_output_type(struct i2c_client *client, int output)
487 {
488         struct saa7127_state *state = i2c_get_clientdata(client);
489
490         switch (output) {
491         case SAA7127_OUTPUT_TYPE_RGB:
492                 state->reg_2d = 0x0f;   /* RGB + CVBS (for sync) */
493                 state->reg_3a = 0x13;   /* by default switch YUV to RGB-matrix on */
494                 break;
495
496         case SAA7127_OUTPUT_TYPE_COMPOSITE:
497                 state->reg_2d = 0x08;   /* 00001000 CVBS only, RGB DAC's off (high impedance mode) */
498                 state->reg_3a = 0x13;   /* by default switch YUV to RGB-matrix on */
499                 break;
500
501         case SAA7127_OUTPUT_TYPE_SVIDEO:
502                 state->reg_2d = 0xff;   /* 11111111  croma -> R, luma -> CVBS + G + B */
503                 state->reg_3a = 0x13;   /* by default switch YUV to RGB-matrix on */
504                 break;
505
506         case SAA7127_OUTPUT_TYPE_YUV_V:
507                 state->reg_2d = 0x4f;   /* reg 2D = 01001111, all DAC's on, RGB + VBS */
508                 state->reg_3a = 0x0b;   /* reg 3A = 00001011, bypass RGB-matrix */
509                 break;
510
511         case SAA7127_OUTPUT_TYPE_YUV_C:
512                 state->reg_2d = 0x0f;   /* reg 2D = 00001111, all DAC's on, RGB + CVBS */
513                 state->reg_3a = 0x0b;   /* reg 3A = 00001011, bypass RGB-matrix */
514                 break;
515
516         case SAA7127_OUTPUT_TYPE_BOTH:
517                 state->reg_2d = 0xbf;
518                 state->reg_3a = 0x13;   /* by default switch YUV to RGB-matrix on */
519                 break;
520
521         default:
522                 return -EINVAL;
523         }
524         v4l_dbg(1, debug, client, "Selecting %s output type\n", output_strs[output]);
525
526         /* Configure Encoder */
527         saa7127_write(client, 0x2d, state->reg_2d);
528         saa7127_write(client, 0x3a, state->reg_3a | state->reg_3a_cb);
529         state->output_type = output;
530         return 0;
531 }
532
533 /* ----------------------------------------------------------------------- */
534
535 static int saa7127_set_input_type(struct i2c_client *client, int input)
536 {
537         struct saa7127_state *state = i2c_get_clientdata(client);
538
539         switch (input) {
540         case SAA7127_INPUT_TYPE_NORMAL: /* avia */
541                 v4l_dbg(1, debug, client, "Selecting Normal Encoder Input\n");
542                 state->reg_3a_cb = 0;
543                 break;
544
545         case SAA7127_INPUT_TYPE_TEST_IMAGE:     /* color bar */
546                 v4l_dbg(1, debug, client, "Selecting Color Bar generator\n");
547                 state->reg_3a_cb = 0x80;
548                 break;
549
550         default:
551                 return -EINVAL;
552         }
553         saa7127_write(client, 0x3a, state->reg_3a | state->reg_3a_cb);
554         state->input_type = input;
555         return 0;
556 }
557
558 /* ----------------------------------------------------------------------- */
559
560 static int saa7127_command(struct i2c_client *client,
561                            unsigned int cmd, void *arg)
562 {
563         struct saa7127_state *state = i2c_get_clientdata(client);
564         struct v4l2_format *fmt = arg;
565         int *iarg = arg;
566
567         switch (cmd) {
568         case VIDIOC_S_STD:
569                 if (state->std == *(v4l2_std_id *)arg)
570                         break;
571                 return saa7127_set_std(client, *(v4l2_std_id *)arg);
572
573         case VIDIOC_G_STD:
574                 *(v4l2_std_id *)arg = state->std;
575                 break;
576
577         case VIDIOC_S_INPUT:
578                 if (state->input_type == *iarg)
579                         break;
580                 return saa7127_set_input_type(client, *iarg);
581
582         case VIDIOC_S_OUTPUT:
583                 if (state->output_type == *iarg)
584                         break;
585                 return saa7127_set_output_type(client, *iarg);
586
587         case VIDIOC_STREAMON:
588         case VIDIOC_STREAMOFF:
589                 if (state->video_enable == (cmd == VIDIOC_STREAMON))
590                         break;
591                 return saa7127_set_video_enable(client, cmd == VIDIOC_STREAMON);
592
593         case VIDIOC_G_FMT:
594                 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
595                         return -EINVAL;
596
597                 memset(&fmt->fmt.sliced, 0, sizeof(fmt->fmt.sliced));
598                 if (state->vps_enable)
599                         fmt->fmt.sliced.service_lines[0][16] = V4L2_SLICED_VPS;
600                 if (state->wss_enable)
601                         fmt->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
602                 if (state->cc_enable) {
603                         fmt->fmt.sliced.service_lines[0][21] = V4L2_SLICED_CAPTION_525;
604                         fmt->fmt.sliced.service_lines[1][21] = V4L2_SLICED_CAPTION_525;
605                 }
606                 fmt->fmt.sliced.service_set =
607                         (state->vps_enable ? V4L2_SLICED_VPS : 0) |
608                         (state->wss_enable ? V4L2_SLICED_WSS_625 : 0) |
609                         (state->cc_enable ? V4L2_SLICED_CAPTION_525 : 0);
610                 break;
611
612         case VIDIOC_LOG_STATUS:
613                 v4l_info(client, "Standard: %s\n", (state->std & V4L2_STD_525_60) ? "60 Hz" : "50 Hz");
614                 v4l_info(client, "Input:    %s\n", state->input_type ?  "color bars" : "normal");
615                 v4l_info(client, "Output:   %s\n", state->video_enable ?
616                         output_strs[state->output_type] : "disabled");
617                 v4l_info(client, "WSS:      %s\n", state->wss_enable ?
618                         wss_strs[state->wss_mode] : "disabled");
619                 v4l_info(client, "VPS:      %s\n", state->vps_enable ? "enabled" : "disabled");
620                 v4l_info(client, "CC:       %s\n", state->cc_enable ? "enabled" : "disabled");
621                 break;
622
623 #ifdef CONFIG_VIDEO_ADV_DEBUG
624         case VIDIOC_INT_G_REGISTER:
625         {
626                 struct v4l2_register *reg = arg;
627
628                 if (reg->i2c_id != I2C_DRIVERID_SAA7127)
629                         return -EINVAL;
630                 reg->val = saa7127_read(client, reg->reg & 0xff);
631                 break;
632         }
633
634         case VIDIOC_INT_S_REGISTER:
635         {
636                 struct v4l2_register *reg = arg;
637
638                 if (reg->i2c_id != I2C_DRIVERID_SAA7127)
639                         return -EINVAL;
640                 if (!capable(CAP_SYS_ADMIN))
641                         return -EPERM;
642                 saa7127_write(client, reg->reg & 0xff, reg->val & 0xff);
643                 break;
644         }
645 #endif
646
647         case VIDIOC_INT_S_VBI_DATA:
648         {
649                 struct v4l2_sliced_vbi_data *data = arg;
650
651                 switch (data->id) {
652                         case V4L2_SLICED_WSS_625:
653                                 return saa7127_set_wss(client, data);
654                         case V4L2_SLICED_VPS:
655                                 return saa7127_set_vps(client, data);
656                         case V4L2_SLICED_CAPTION_525:
657                                 if (data->field == 0)
658                                         return saa7127_set_cc(client, data);
659                                 return saa7127_set_xds(client, data);
660                         default:
661                                 return -EINVAL;
662                 }
663                 break;
664         }
665
666         case VIDIOC_INT_G_CHIP_IDENT:
667                 *(enum v4l2_chip_ident *)arg = state->ident;
668                 break;
669
670         default:
671                 return -EINVAL;
672         }
673         return 0;
674 }
675
676 /* ----------------------------------------------------------------------- */
677
678 static struct i2c_driver i2c_driver_saa7127;
679
680 /* ----------------------------------------------------------------------- */
681
682 static int saa7127_attach(struct i2c_adapter *adapter, int address, int kind)
683 {
684         struct i2c_client *client;
685         struct saa7127_state *state;
686         struct v4l2_sliced_vbi_data vbi = { 0, 0, 0, 0 };  /* set to disabled */
687         int read_result = 0;
688
689         /* Check if the adapter supports the needed features */
690         if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
691                 return 0;
692
693         client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
694         if (client == 0)
695                 return -ENOMEM;
696
697         client->addr = address;
698         client->adapter = adapter;
699         client->driver = &i2c_driver_saa7127;
700         snprintf(client->name, sizeof(client->name) - 1, "saa7127");
701
702         v4l_dbg(1, debug, client, "detecting saa7127 client on address 0x%x\n", address << 1);
703
704         /* First test register 0: Bits 5-7 are a version ID (should be 0),
705            and bit 2 should also be 0.
706            This is rather general, so the second test is more specific and
707            looks at the 'ending point of burst in clock cycles' which is
708            0x1d after a reset and not expected to ever change. */
709         if ((saa7127_read(client, 0) & 0xe4) != 0 ||
710                         (saa7127_read(client, 0x29) & 0x3f) != 0x1d) {
711                 v4l_dbg(1, debug, client, "saa7127 not found\n");
712                 kfree(client);
713                 return 0;
714         }
715         state = kzalloc(sizeof(struct saa7127_state), GFP_KERNEL);
716
717         if (state == NULL) {
718                 kfree(client);
719                 return (-ENOMEM);
720         }
721
722         i2c_set_clientdata(client, state);
723
724         /* Configure Encoder */
725
726         v4l_dbg(1, debug, client, "Configuring encoder\n");
727         saa7127_write_inittab(client, saa7127_init_config_common);
728         saa7127_set_std(client, V4L2_STD_NTSC);
729         saa7127_set_output_type(client, SAA7127_OUTPUT_TYPE_BOTH);
730         saa7127_set_vps(client, &vbi);
731         saa7127_set_wss(client, &vbi);
732         saa7127_set_cc(client, &vbi);
733         saa7127_set_xds(client, &vbi);
734         if (test_image == 1) {
735                 /* The Encoder has an internal Colorbar generator */
736                 /* This can be used for debugging */
737                 saa7127_set_input_type(client, SAA7127_INPUT_TYPE_TEST_IMAGE);
738         } else {
739                 saa7127_set_input_type(client, SAA7127_INPUT_TYPE_NORMAL);
740         }
741         saa7127_set_video_enable(client, 1);
742
743         /* Detect if it's an saa7129 */
744         read_result = saa7127_read(client, SAA7129_REG_FADE_KEY_COL2);
745         saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, 0xaa);
746         if (saa7127_read(client, SAA7129_REG_FADE_KEY_COL2) == 0xaa) {
747                 v4l_info(client, "saa7129 found @ 0x%x (%s)\n", address << 1, adapter->name);
748                 saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, read_result);
749                 saa7127_write_inittab(client, saa7129_init_config_extra);
750                 state->ident = V4L2_IDENT_SAA7129;
751         } else {
752                 v4l_info(client, "saa7127 found @ 0x%x (%s)\n", address << 1, adapter->name);
753                 state->ident = V4L2_IDENT_SAA7127;
754         }
755
756         i2c_attach_client(client);
757
758         return 0;
759 }
760
761 /* ----------------------------------------------------------------------- */
762
763 static int saa7127_probe(struct i2c_adapter *adapter)
764 {
765         if (adapter->class & I2C_CLASS_TV_ANALOG)
766                 return i2c_probe(adapter, &addr_data, saa7127_attach);
767         return 0;
768 }
769
770 /* ----------------------------------------------------------------------- */
771
772 static int saa7127_detach(struct i2c_client *client)
773 {
774         struct saa7127_state *state = i2c_get_clientdata(client);
775         int err;
776
777         /* Turn off TV output */
778         saa7127_set_video_enable(client, 0);
779
780         err = i2c_detach_client(client);
781
782         if (err) {
783                 return err;
784         }
785
786         kfree(state);
787         kfree(client);
788         return 0;
789 }
790
791 /* ----------------------------------------------------------------------- */
792
793 static struct i2c_driver i2c_driver_saa7127 = {
794         .driver = {
795                 .name = "saa7127",
796         },
797         .id = I2C_DRIVERID_SAA7127,
798         .attach_adapter = saa7127_probe,
799         .detach_client = saa7127_detach,
800         .command = saa7127_command,
801 };
802
803
804 /* ----------------------------------------------------------------------- */
805
806 static int __init saa7127_init_module(void)
807 {
808         return i2c_add_driver(&i2c_driver_saa7127);
809 }
810
811 /* ----------------------------------------------------------------------- */
812
813 static void __exit saa7127_cleanup_module(void)
814 {
815         i2c_del_driver(&i2c_driver_saa7127);
816 }
817
818 /* ----------------------------------------------------------------------- */
819
820 module_init(saa7127_init_module);
821 module_exit(saa7127_cleanup_module);