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