]> err.no Git - linux-2.6/blob - drivers/media/video/saa7127.c
0262acde0888dcc446ebc39fa2a0b9e7880e9bdb
[linux-2.6] / 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 #include <media/v4l2-chip-ident.h>
58 #include <media/v4l2-i2c-drv-legacy.h>
59 #include <media/saa7127.h>
60
61 static int debug = 0;
62 static int test_image = 0;
63
64 MODULE_DESCRIPTION("Philips SAA7127/9 video encoder driver");
65 MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil");
66 MODULE_LICENSE("GPL");
67 module_param(debug, int, 0644);
68 module_param(test_image, int, 0644);
69 MODULE_PARM_DESC(debug, "debug level (0-2)");
70 MODULE_PARM_DESC(test_image, "test_image (0-1)");
71
72 static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
73
74
75 I2C_CLIENT_INSMOD;
76
77 /*
78  * SAA7127 registers
79  */
80
81 #define SAA7127_REG_STATUS                           0x00
82 #define SAA7127_REG_WIDESCREEN_CONFIG                0x26
83 #define SAA7127_REG_WIDESCREEN_ENABLE                0x27
84 #define SAA7127_REG_BURST_START                      0x28
85 #define SAA7127_REG_BURST_END                        0x29
86 #define SAA7127_REG_COPYGEN_0                        0x2a
87 #define SAA7127_REG_COPYGEN_1                        0x2b
88 #define SAA7127_REG_COPYGEN_2                        0x2c
89 #define SAA7127_REG_OUTPUT_PORT_CONTROL              0x2d
90 #define SAA7127_REG_GAIN_LUMINANCE_RGB               0x38
91 #define SAA7127_REG_GAIN_COLORDIFF_RGB               0x39
92 #define SAA7127_REG_INPUT_PORT_CONTROL_1             0x3a
93 #define SAA7129_REG_FADE_KEY_COL2                    0x4f
94 #define SAA7127_REG_CHROMA_PHASE                     0x5a
95 #define SAA7127_REG_GAINU                            0x5b
96 #define SAA7127_REG_GAINV                            0x5c
97 #define SAA7127_REG_BLACK_LEVEL                      0x5d
98 #define SAA7127_REG_BLANKING_LEVEL                   0x5e
99 #define SAA7127_REG_VBI_BLANKING                     0x5f
100 #define SAA7127_REG_DAC_CONTROL                      0x61
101 #define SAA7127_REG_BURST_AMP                        0x62
102 #define SAA7127_REG_SUBC3                            0x63
103 #define SAA7127_REG_SUBC2                            0x64
104 #define SAA7127_REG_SUBC1                            0x65
105 #define SAA7127_REG_SUBC0                            0x66
106 #define SAA7127_REG_LINE_21_ODD_0                    0x67
107 #define SAA7127_REG_LINE_21_ODD_1                    0x68
108 #define SAA7127_REG_LINE_21_EVEN_0                   0x69
109 #define SAA7127_REG_LINE_21_EVEN_1                   0x6a
110 #define SAA7127_REG_RCV_PORT_CONTROL                 0x6b
111 #define SAA7127_REG_VTRIG                            0x6c
112 #define SAA7127_REG_HTRIG_HI                         0x6d
113 #define SAA7127_REG_MULTI                            0x6e
114 #define SAA7127_REG_CLOSED_CAPTION                   0x6f
115 #define SAA7127_REG_RCV2_OUTPUT_START                0x70
116 #define SAA7127_REG_RCV2_OUTPUT_END                  0x71
117 #define SAA7127_REG_RCV2_OUTPUT_MSBS                 0x72
118 #define SAA7127_REG_TTX_REQUEST_H_START              0x73
119 #define SAA7127_REG_TTX_REQUEST_H_DELAY_LENGTH       0x74
120 #define SAA7127_REG_CSYNC_ADVANCE_VSYNC_SHIFT        0x75
121 #define SAA7127_REG_TTX_ODD_REQ_VERT_START           0x76
122 #define SAA7127_REG_TTX_ODD_REQ_VERT_END             0x77
123 #define SAA7127_REG_TTX_EVEN_REQ_VERT_START          0x78
124 #define SAA7127_REG_TTX_EVEN_REQ_VERT_END            0x79
125 #define SAA7127_REG_FIRST_ACTIVE                     0x7a
126 #define SAA7127_REG_LAST_ACTIVE                      0x7b
127 #define SAA7127_REG_MSB_VERTICAL                     0x7c
128 #define SAA7127_REG_DISABLE_TTX_LINE_LO_0            0x7e
129 #define SAA7127_REG_DISABLE_TTX_LINE_LO_1            0x7f
130
131 /*
132  **********************************************************************
133  *
134  *  Arrays with configuration parameters for the SAA7127
135  *
136  **********************************************************************
137  */
138
139 struct i2c_reg_value {
140         unsigned char reg;
141         unsigned char value;
142 };
143
144 static const struct i2c_reg_value saa7129_init_config_extra[] = {
145         { SAA7127_REG_OUTPUT_PORT_CONTROL,              0x38 },
146         { SAA7127_REG_VTRIG,                            0xfa },
147         { 0, 0 }
148 };
149
150 static const struct i2c_reg_value saa7127_init_config_common[] = {
151         { SAA7127_REG_WIDESCREEN_CONFIG,                0x0d },
152         { SAA7127_REG_WIDESCREEN_ENABLE,                0x00 },
153         { SAA7127_REG_COPYGEN_0,                        0x77 },
154         { SAA7127_REG_COPYGEN_1,                        0x41 },
155         { SAA7127_REG_COPYGEN_2,                        0x00 }, /* Macrovision enable/disable */
156         { SAA7127_REG_OUTPUT_PORT_CONTROL,              0x9e },
157         { SAA7127_REG_GAIN_LUMINANCE_RGB,               0x00 },
158         { SAA7127_REG_GAIN_COLORDIFF_RGB,               0x00 },
159         { SAA7127_REG_INPUT_PORT_CONTROL_1,             0x80 }, /* for color bars */
160         { SAA7127_REG_LINE_21_ODD_0,                    0x77 },
161         { SAA7127_REG_LINE_21_ODD_1,                    0x41 },
162         { SAA7127_REG_LINE_21_EVEN_0,                   0x88 },
163         { SAA7127_REG_LINE_21_EVEN_1,                   0x41 },
164         { SAA7127_REG_RCV_PORT_CONTROL,                 0x12 },
165         { SAA7127_REG_VTRIG,                            0xf9 },
166         { SAA7127_REG_HTRIG_HI,                         0x00 },
167         { SAA7127_REG_RCV2_OUTPUT_START,                0x41 },
168         { SAA7127_REG_RCV2_OUTPUT_END,                  0xc3 },
169         { SAA7127_REG_RCV2_OUTPUT_MSBS,                 0x00 },
170         { SAA7127_REG_TTX_REQUEST_H_START,              0x3e },
171         { SAA7127_REG_TTX_REQUEST_H_DELAY_LENGTH,       0xb8 },
172         { SAA7127_REG_CSYNC_ADVANCE_VSYNC_SHIFT,        0x03 },
173         { SAA7127_REG_TTX_ODD_REQ_VERT_START,           0x15 },
174         { SAA7127_REG_TTX_ODD_REQ_VERT_END,             0x16 },
175         { SAA7127_REG_TTX_EVEN_REQ_VERT_START,          0x15 },
176         { SAA7127_REG_TTX_EVEN_REQ_VERT_END,            0x16 },
177         { SAA7127_REG_FIRST_ACTIVE,                     0x1a },
178         { SAA7127_REG_LAST_ACTIVE,                      0x01 },
179         { SAA7127_REG_MSB_VERTICAL,                     0xc0 },
180         { SAA7127_REG_DISABLE_TTX_LINE_LO_0,            0x00 },
181         { SAA7127_REG_DISABLE_TTX_LINE_LO_1,            0x00 },
182         { 0, 0 }
183 };
184
185 #define SAA7127_60HZ_DAC_CONTROL 0x15
186 static const struct i2c_reg_value saa7127_init_config_60hz[] = {
187         { SAA7127_REG_BURST_START,                      0x19 },
188         /* BURST_END is also used as a chip ID in saa7127_detect_client */
189         { SAA7127_REG_BURST_END,                        0x1d },
190         { SAA7127_REG_CHROMA_PHASE,                     0xa3 },
191         { SAA7127_REG_GAINU,                            0x98 },
192         { SAA7127_REG_GAINV,                            0xd3 },
193         { SAA7127_REG_BLACK_LEVEL,                      0x39 },
194         { SAA7127_REG_BLANKING_LEVEL,                   0x2e },
195         { SAA7127_REG_VBI_BLANKING,                     0x2e },
196         { SAA7127_REG_DAC_CONTROL,                      0x15 },
197         { SAA7127_REG_BURST_AMP,                        0x4d },
198         { SAA7127_REG_SUBC3,                            0x1f },
199         { SAA7127_REG_SUBC2,                            0x7c },
200         { SAA7127_REG_SUBC1,                            0xf0 },
201         { SAA7127_REG_SUBC0,                            0x21 },
202         { SAA7127_REG_MULTI,                            0x90 },
203         { SAA7127_REG_CLOSED_CAPTION,                   0x11 },
204         { 0, 0 }
205 };
206
207 #define SAA7127_50HZ_DAC_CONTROL 0x02
208 static struct i2c_reg_value saa7127_init_config_50hz[] = {
209         { SAA7127_REG_BURST_START,                      0x21 },
210         /* BURST_END is also used as a chip ID in saa7127_detect_client */
211         { SAA7127_REG_BURST_END,                        0x1d },
212         { SAA7127_REG_CHROMA_PHASE,                     0x3f },
213         { SAA7127_REG_GAINU,                            0x7d },
214         { SAA7127_REG_GAINV,                            0xaf },
215         { SAA7127_REG_BLACK_LEVEL,                      0x33 },
216         { SAA7127_REG_BLANKING_LEVEL,                   0x35 },
217         { SAA7127_REG_VBI_BLANKING,                     0x35 },
218         { SAA7127_REG_DAC_CONTROL,                      0x02 },
219         { SAA7127_REG_BURST_AMP,                        0x2f },
220         { SAA7127_REG_SUBC3,                            0xcb },
221         { SAA7127_REG_SUBC2,                            0x8a },
222         { SAA7127_REG_SUBC1,                            0x09 },
223         { SAA7127_REG_SUBC0,                            0x2a },
224         { SAA7127_REG_MULTI,                            0xa0 },
225         { SAA7127_REG_CLOSED_CAPTION,                   0x00 },
226         { 0, 0 }
227 };
228
229 /*
230  **********************************************************************
231  *
232  *  Encoder Struct, holds the configuration state of the encoder
233  *
234  **********************************************************************
235  */
236
237 struct saa7127_state {
238         v4l2_std_id std;
239         u32 ident;
240         enum saa7127_input_type input_type;
241         enum saa7127_output_type output_type;
242         int video_enable;
243         int wss_enable;
244         u16 wss_mode;
245         int cc_enable;
246         u16 cc_data;
247         int xds_enable;
248         u16 xds_data;
249         int vps_enable;
250         u8 vps_data[5];
251         u8 reg_2d;
252         u8 reg_3a;
253         u8 reg_3a_cb;   /* colorbar bit */
254         u8 reg_61;
255 };
256
257 static const char * const output_strs[] =
258 {
259         "S-Video + Composite",
260         "Composite",
261         "S-Video",
262         "RGB",
263         "YUV C",
264         "YUV V"
265 };
266
267 static const char * const wss_strs[] = {
268         "invalid",
269         "letterbox 14:9 center",
270         "letterbox 14:9 top",
271         "invalid",
272         "letterbox 16:9 top",
273         "invalid",
274         "invalid",
275         "16:9 full format anamorphic",
276         "4:3 full format",
277         "invalid",
278         "invalid",
279         "letterbox 16:9 center",
280         "invalid",
281         "letterbox >16:9 center",
282         "14:9 full format center",
283         "invalid",
284 };
285
286 /* ----------------------------------------------------------------------- */
287
288 static int saa7127_read(struct i2c_client *client, u8 reg)
289 {
290         return i2c_smbus_read_byte_data(client, reg);
291 }
292
293 /* ----------------------------------------------------------------------- */
294
295 static int saa7127_write(struct i2c_client *client, u8 reg, u8 val)
296 {
297         int i;
298
299         for (i = 0; i < 3; i++) {
300                 if (i2c_smbus_write_byte_data(client, reg, val) == 0)
301                         return 0;
302         }
303         v4l_err(client, "I2C Write Problem\n");
304         return -1;
305 }
306
307 /* ----------------------------------------------------------------------- */
308
309 static int saa7127_write_inittab(struct i2c_client *client,
310                                  const struct i2c_reg_value *regs)
311 {
312         while (regs->reg != 0) {
313                 saa7127_write(client, regs->reg, regs->value);
314                 regs++;
315         }
316         return 0;
317 }
318
319 /* ----------------------------------------------------------------------- */
320
321 static int saa7127_set_vps(struct i2c_client *client, struct v4l2_sliced_vbi_data *data)
322 {
323         struct saa7127_state *state = i2c_get_clientdata(client);
324         int enable = (data->line != 0);
325
326         if (enable && (data->field != 0 || data->line != 16))
327                 return -EINVAL;
328         if (state->vps_enable != enable) {
329                 v4l_dbg(1, debug, client, "Turn VPS Signal %s\n", enable ? "on" : "off");
330                 saa7127_write(client, 0x54, enable << 7);
331                 state->vps_enable = enable;
332         }
333         if (!enable)
334                 return 0;
335
336         state->vps_data[0] = data->data[2];
337         state->vps_data[1] = data->data[8];
338         state->vps_data[2] = data->data[9];
339         state->vps_data[3] = data->data[10];
340         state->vps_data[4] = data->data[11];
341         v4l_dbg(1, debug, client, "Set VPS data %02x %02x %02x %02x %02x\n",
342                 state->vps_data[0], state->vps_data[1],
343                 state->vps_data[2], state->vps_data[3],
344                 state->vps_data[4]);
345         saa7127_write(client, 0x55, state->vps_data[0]);
346         saa7127_write(client, 0x56, state->vps_data[1]);
347         saa7127_write(client, 0x57, state->vps_data[2]);
348         saa7127_write(client, 0x58, state->vps_data[3]);
349         saa7127_write(client, 0x59, state->vps_data[4]);
350         return 0;
351 }
352
353 /* ----------------------------------------------------------------------- */
354
355 static int saa7127_set_cc(struct i2c_client *client, struct v4l2_sliced_vbi_data *data)
356 {
357         struct saa7127_state *state = i2c_get_clientdata(client);
358         u16 cc = data->data[1] << 8 | data->data[0];
359         int enable = (data->line != 0);
360
361         if (enable && (data->field != 0 || data->line != 21))
362                 return -EINVAL;
363         if (state->cc_enable != enable) {
364                 v4l_dbg(1, debug, client, "Turn CC %s\n", enable ? "on" : "off");
365                 saa7127_write(client, SAA7127_REG_CLOSED_CAPTION,
366                                 (state->xds_enable << 7) | (enable << 6) | 0x11);
367                 state->cc_enable = enable;
368         }
369         if (!enable)
370                 return 0;
371
372         v4l_dbg(2, debug, client, "CC data: %04x\n", cc);
373         saa7127_write(client, SAA7127_REG_LINE_21_ODD_0, cc & 0xff);
374         saa7127_write(client, SAA7127_REG_LINE_21_ODD_1, cc >> 8);
375         state->cc_data = cc;
376         return 0;
377 }
378
379 /* ----------------------------------------------------------------------- */
380
381 static int saa7127_set_xds(struct i2c_client *client, struct v4l2_sliced_vbi_data *data)
382 {
383         struct saa7127_state *state = i2c_get_clientdata(client);
384         u16 xds = data->data[1] << 8 | data->data[0];
385         int enable = (data->line != 0);
386
387         if (enable && (data->field != 1 || data->line != 21))
388                 return -EINVAL;
389         if (state->xds_enable != enable) {
390                 v4l_dbg(1, debug, client, "Turn XDS %s\n", enable ? "on" : "off");
391                 saa7127_write(client, SAA7127_REG_CLOSED_CAPTION,
392                                 (enable << 7) | (state->cc_enable << 6) | 0x11);
393                 state->xds_enable = enable;
394         }
395         if (!enable)
396                 return 0;
397
398         v4l_dbg(2, debug, client, "XDS data: %04x\n", xds);
399         saa7127_write(client, SAA7127_REG_LINE_21_EVEN_0, xds & 0xff);
400         saa7127_write(client, SAA7127_REG_LINE_21_EVEN_1, xds >> 8);
401         state->xds_data = xds;
402         return 0;
403 }
404
405 /* ----------------------------------------------------------------------- */
406
407 static int saa7127_set_wss(struct i2c_client *client, struct v4l2_sliced_vbi_data *data)
408 {
409         struct saa7127_state *state = i2c_get_clientdata(client);
410         int enable = (data->line != 0);
411
412         if (enable && (data->field != 0 || data->line != 23))
413                 return -EINVAL;
414         if (state->wss_enable != enable) {
415                 v4l_dbg(1, debug, client, "Turn WSS %s\n", enable ? "on" : "off");
416                 saa7127_write(client, 0x27, enable << 7);
417                 state->wss_enable = enable;
418         }
419         if (!enable)
420                 return 0;
421
422         saa7127_write(client, 0x26, data->data[0]);
423         saa7127_write(client, 0x27, 0x80 | (data->data[1] & 0x3f));
424         v4l_dbg(1, debug, client, "WSS mode: %s\n", wss_strs[data->data[0] & 0xf]);
425         state->wss_mode = (data->data[1] & 0x3f) << 8 | data->data[0];
426         return 0;
427 }
428
429 /* ----------------------------------------------------------------------- */
430
431 static int saa7127_set_video_enable(struct i2c_client *client, int enable)
432 {
433         struct saa7127_state *state = i2c_get_clientdata(client);
434
435         if (enable) {
436                 v4l_dbg(1, debug, client, "Enable Video Output\n");
437                 saa7127_write(client, 0x2d, state->reg_2d);
438                 saa7127_write(client, 0x61, state->reg_61);
439         } else {
440                 v4l_dbg(1, debug, client, "Disable Video Output\n");
441                 saa7127_write(client, 0x2d, (state->reg_2d & 0xf0));
442                 saa7127_write(client, 0x61, (state->reg_61 | 0xc0));
443         }
444         state->video_enable = enable;
445         return 0;
446 }
447
448 /* ----------------------------------------------------------------------- */
449
450 static int saa7127_set_std(struct i2c_client *client, v4l2_std_id std)
451 {
452         struct saa7127_state *state = i2c_get_clientdata(client);
453         const struct i2c_reg_value *inittab;
454
455         if (std & V4L2_STD_525_60) {
456                 v4l_dbg(1, debug, client, "Selecting 60 Hz video Standard\n");
457                 inittab = saa7127_init_config_60hz;
458                 state->reg_61 = SAA7127_60HZ_DAC_CONTROL;
459         } else {
460                 v4l_dbg(1, debug, client, "Selecting 50 Hz video Standard\n");
461                 inittab = saa7127_init_config_50hz;
462                 state->reg_61 = SAA7127_50HZ_DAC_CONTROL;
463         }
464
465         /* Write Table */
466         saa7127_write_inittab(client, inittab);
467         state->std = std;
468         return 0;
469 }
470
471 /* ----------------------------------------------------------------------- */
472
473 static int saa7127_set_output_type(struct i2c_client *client, int output)
474 {
475         struct saa7127_state *state = i2c_get_clientdata(client);
476
477         switch (output) {
478         case SAA7127_OUTPUT_TYPE_RGB:
479                 state->reg_2d = 0x0f;   /* RGB + CVBS (for sync) */
480                 state->reg_3a = 0x13;   /* by default switch YUV to RGB-matrix on */
481                 break;
482
483         case SAA7127_OUTPUT_TYPE_COMPOSITE:
484                 state->reg_2d = 0x08;   /* 00001000 CVBS only, RGB DAC's off (high impedance mode) */
485                 state->reg_3a = 0x13;   /* by default switch YUV to RGB-matrix on */
486                 break;
487
488         case SAA7127_OUTPUT_TYPE_SVIDEO:
489                 state->reg_2d = 0xff;   /* 11111111  croma -> R, luma -> CVBS + G + B */
490                 state->reg_3a = 0x13;   /* by default switch YUV to RGB-matrix on */
491                 break;
492
493         case SAA7127_OUTPUT_TYPE_YUV_V:
494                 state->reg_2d = 0x4f;   /* reg 2D = 01001111, all DAC's on, RGB + VBS */
495                 state->reg_3a = 0x0b;   /* reg 3A = 00001011, bypass RGB-matrix */
496                 break;
497
498         case SAA7127_OUTPUT_TYPE_YUV_C:
499                 state->reg_2d = 0x0f;   /* reg 2D = 00001111, all DAC's on, RGB + CVBS */
500                 state->reg_3a = 0x0b;   /* reg 3A = 00001011, bypass RGB-matrix */
501                 break;
502
503         case SAA7127_OUTPUT_TYPE_BOTH:
504                 state->reg_2d = 0xbf;
505                 state->reg_3a = 0x13;   /* by default switch YUV to RGB-matrix on */
506                 break;
507
508         default:
509                 return -EINVAL;
510         }
511         v4l_dbg(1, debug, client, "Selecting %s output type\n", output_strs[output]);
512
513         /* Configure Encoder */
514         saa7127_write(client, 0x2d, state->reg_2d);
515         saa7127_write(client, 0x3a, state->reg_3a | state->reg_3a_cb);
516         state->output_type = output;
517         return 0;
518 }
519
520 /* ----------------------------------------------------------------------- */
521
522 static int saa7127_set_input_type(struct i2c_client *client, int input)
523 {
524         struct saa7127_state *state = i2c_get_clientdata(client);
525
526         switch (input) {
527         case SAA7127_INPUT_TYPE_NORMAL: /* avia */
528                 v4l_dbg(1, debug, client, "Selecting Normal Encoder Input\n");
529                 state->reg_3a_cb = 0;
530                 break;
531
532         case SAA7127_INPUT_TYPE_TEST_IMAGE:     /* color bar */
533                 v4l_dbg(1, debug, client, "Selecting Color Bar generator\n");
534                 state->reg_3a_cb = 0x80;
535                 break;
536
537         default:
538                 return -EINVAL;
539         }
540         saa7127_write(client, 0x3a, state->reg_3a | state->reg_3a_cb);
541         state->input_type = input;
542         return 0;
543 }
544
545 /* ----------------------------------------------------------------------- */
546
547 static int saa7127_command(struct i2c_client *client,
548                            unsigned int cmd, void *arg)
549 {
550         struct saa7127_state *state = i2c_get_clientdata(client);
551         struct v4l2_format *fmt = arg;
552         struct v4l2_routing *route = arg;
553
554         switch (cmd) {
555         case VIDIOC_INT_S_STD_OUTPUT:
556                 if (state->std == *(v4l2_std_id *)arg)
557                         break;
558                 return saa7127_set_std(client, *(v4l2_std_id *)arg);
559
560         case VIDIOC_INT_G_STD_OUTPUT:
561                 *(v4l2_std_id *)arg = state->std;
562                 break;
563
564         case VIDIOC_INT_G_VIDEO_ROUTING:
565                 route->input = state->input_type;
566                 route->output = state->output_type;
567                 break;
568
569         case VIDIOC_INT_S_VIDEO_ROUTING:
570         {
571                 int rc = 0;
572
573                 if (state->input_type != route->input) {
574                         rc = saa7127_set_input_type(client, route->input);
575                 }
576                 if (rc == 0 && state->output_type != route->output) {
577                         rc = saa7127_set_output_type(client, route->output);
578                 }
579                 return rc;
580         }
581
582         case VIDIOC_STREAMON:
583         case VIDIOC_STREAMOFF:
584                 if (state->video_enable == (cmd == VIDIOC_STREAMON))
585                         break;
586                 return saa7127_set_video_enable(client, cmd == VIDIOC_STREAMON);
587
588         case VIDIOC_G_FMT:
589                 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
590                         return -EINVAL;
591
592                 memset(&fmt->fmt.sliced, 0, sizeof(fmt->fmt.sliced));
593                 if (state->vps_enable)
594                         fmt->fmt.sliced.service_lines[0][16] = V4L2_SLICED_VPS;
595                 if (state->wss_enable)
596                         fmt->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
597                 if (state->cc_enable) {
598                         fmt->fmt.sliced.service_lines[0][21] = V4L2_SLICED_CAPTION_525;
599                         fmt->fmt.sliced.service_lines[1][21] = V4L2_SLICED_CAPTION_525;
600                 }
601                 fmt->fmt.sliced.service_set =
602                         (state->vps_enable ? V4L2_SLICED_VPS : 0) |
603                         (state->wss_enable ? V4L2_SLICED_WSS_625 : 0) |
604                         (state->cc_enable ? V4L2_SLICED_CAPTION_525 : 0);
605                 break;
606
607         case VIDIOC_LOG_STATUS:
608                 v4l_info(client, "Standard: %s\n", (state->std & V4L2_STD_525_60) ? "60 Hz" : "50 Hz");
609                 v4l_info(client, "Input:    %s\n", state->input_type ?  "color bars" : "normal");
610                 v4l_info(client, "Output:   %s\n", state->video_enable ?
611                         output_strs[state->output_type] : "disabled");
612                 v4l_info(client, "WSS:      %s\n", state->wss_enable ?
613                         wss_strs[state->wss_mode] : "disabled");
614                 v4l_info(client, "VPS:      %s\n", state->vps_enable ? "enabled" : "disabled");
615                 v4l_info(client, "CC:       %s\n", state->cc_enable ? "enabled" : "disabled");
616                 break;
617
618 #ifdef CONFIG_VIDEO_ADV_DEBUG
619         case VIDIOC_DBG_G_REGISTER:
620         case VIDIOC_DBG_S_REGISTER:
621         {
622                 struct v4l2_register *reg = arg;
623
624                 if (!v4l2_chip_match_i2c_client(client, reg->match_type, reg->match_chip))
625                         return -EINVAL;
626                 if (!capable(CAP_SYS_ADMIN))
627                         return -EPERM;
628                 if (cmd == VIDIOC_DBG_G_REGISTER)
629                         reg->val = saa7127_read(client, reg->reg & 0xff);
630                 else
631                         saa7127_write(client, reg->reg & 0xff, reg->val & 0xff);
632                 break;
633         }
634 #endif
635
636         case VIDIOC_INT_S_VBI_DATA:
637         {
638                 struct v4l2_sliced_vbi_data *data = arg;
639
640                 switch (data->id) {
641                         case V4L2_SLICED_WSS_625:
642                                 return saa7127_set_wss(client, data);
643                         case V4L2_SLICED_VPS:
644                                 return saa7127_set_vps(client, data);
645                         case V4L2_SLICED_CAPTION_525:
646                                 if (data->field == 0)
647                                         return saa7127_set_cc(client, data);
648                                 return saa7127_set_xds(client, data);
649                         default:
650                                 return -EINVAL;
651                 }
652                 break;
653         }
654
655         case VIDIOC_G_CHIP_IDENT:
656                 return v4l2_chip_ident_i2c_client(client, arg, state->ident, 0);
657
658         default:
659                 return -EINVAL;
660         }
661         return 0;
662 }
663
664 /* ----------------------------------------------------------------------- */
665
666 static int saa7127_probe(struct i2c_client *client)
667 {
668         struct saa7127_state *state;
669         struct v4l2_sliced_vbi_data vbi = { 0, 0, 0, 0 };  /* set to disabled */
670         int read_result = 0;
671
672         /* Check if the adapter supports the needed features */
673         if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
674                 return -EIO;
675
676         snprintf(client->name, sizeof(client->name) - 1, "saa7127");
677
678         v4l_dbg(1, debug, client, "detecting saa7127 client on address 0x%x\n", client->addr << 1);
679
680         /* First test register 0: Bits 5-7 are a version ID (should be 0),
681            and bit 2 should also be 0.
682            This is rather general, so the second test is more specific and
683            looks at the 'ending point of burst in clock cycles' which is
684            0x1d after a reset and not expected to ever change. */
685         if ((saa7127_read(client, 0) & 0xe4) != 0 ||
686                         (saa7127_read(client, 0x29) & 0x3f) != 0x1d) {
687                 v4l_dbg(1, debug, client, "saa7127 not found\n");
688                 return -ENODEV;
689         }
690         state = kzalloc(sizeof(struct saa7127_state), GFP_KERNEL);
691
692         if (state == NULL) {
693                 return -ENOMEM;
694         }
695
696         i2c_set_clientdata(client, state);
697
698         /* Configure Encoder */
699
700         v4l_dbg(1, debug, client, "Configuring encoder\n");
701         saa7127_write_inittab(client, saa7127_init_config_common);
702         saa7127_set_std(client, V4L2_STD_NTSC);
703         saa7127_set_output_type(client, SAA7127_OUTPUT_TYPE_BOTH);
704         saa7127_set_vps(client, &vbi);
705         saa7127_set_wss(client, &vbi);
706         saa7127_set_cc(client, &vbi);
707         saa7127_set_xds(client, &vbi);
708         if (test_image == 1) {
709                 /* The Encoder has an internal Colorbar generator */
710                 /* This can be used for debugging */
711                 saa7127_set_input_type(client, SAA7127_INPUT_TYPE_TEST_IMAGE);
712         } else {
713                 saa7127_set_input_type(client, SAA7127_INPUT_TYPE_NORMAL);
714         }
715         saa7127_set_video_enable(client, 1);
716
717         /* Detect if it's an saa7129 */
718         read_result = saa7127_read(client, SAA7129_REG_FADE_KEY_COL2);
719         saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, 0xaa);
720         if (saa7127_read(client, SAA7129_REG_FADE_KEY_COL2) == 0xaa) {
721                 v4l_info(client, "saa7129 found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name);
722                 saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, read_result);
723                 saa7127_write_inittab(client, saa7129_init_config_extra);
724                 state->ident = V4L2_IDENT_SAA7129;
725         } else {
726                 v4l_info(client, "saa7127 found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name);
727                 state->ident = V4L2_IDENT_SAA7127;
728         }
729         return 0;
730 }
731
732 /* ----------------------------------------------------------------------- */
733
734 static int saa7127_remove(struct i2c_client *client)
735 {
736         /* Turn off TV output */
737         saa7127_set_video_enable(client, 0);
738         kfree(i2c_get_clientdata(client));
739         return 0;
740 }
741
742 /* ----------------------------------------------------------------------- */
743
744 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
745         .name = "saa7127",
746         .driverid = I2C_DRIVERID_SAA7127,
747         .command = saa7127_command,
748         .probe = saa7127_probe,
749         .remove = saa7127_remove,
750 };
751