a5fbfe025333bd5cadae80a98b192d4e0e34444e
[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 #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
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, "Turn CC %s\n", enable ? "on" : "off");
361                 saa7127_write(client, SAA7127_REG_CLOSED_CAPTION,
362                                 (state->xds_enable << 7) | (enable << 6) | 0x11);
363                 state->cc_enable = enable;
364         }
365         if (!enable)
366                 return 0;
367
368         v4l_dbg(2, debug, client, "CC data: %04x\n", cc);
369         saa7127_write(client, SAA7127_REG_LINE_21_ODD_0, cc & 0xff);
370         saa7127_write(client, SAA7127_REG_LINE_21_ODD_1, cc >> 8);
371         state->cc_data = cc;
372         return 0;
373 }
374
375 /* ----------------------------------------------------------------------- */
376
377 static int saa7127_set_xds(struct i2c_client *client, struct v4l2_sliced_vbi_data *data)
378 {
379         struct saa7127_state *state = i2c_get_clientdata(client);
380         u16 xds = data->data[1] << 8 | data->data[0];
381         int enable = (data->line != 0);
382
383         if (enable && (data->field != 1 || data->line != 21))
384                 return -EINVAL;
385         if (state->xds_enable != enable) {
386                 v4l_dbg(1, debug, client, "Turn XDS %s\n", enable ? "on" : "off");
387                 saa7127_write(client, SAA7127_REG_CLOSED_CAPTION,
388                                 (enable << 7) | (state->cc_enable << 6) | 0x11);
389                 state->xds_enable = enable;
390         }
391         if (!enable)
392                 return 0;
393
394         v4l_dbg(2, debug, client, "XDS data: %04x\n", xds);
395         saa7127_write(client, SAA7127_REG_LINE_21_EVEN_0, xds & 0xff);
396         saa7127_write(client, SAA7127_REG_LINE_21_EVEN_1, xds >> 8);
397         state->xds_data = xds;
398         return 0;
399 }
400
401 /* ----------------------------------------------------------------------- */
402
403 static int saa7127_set_wss(struct i2c_client *client, struct v4l2_sliced_vbi_data *data)
404 {
405         struct saa7127_state *state = i2c_get_clientdata(client);
406         int enable = (data->line != 0);
407
408         if (enable && (data->field != 0 || data->line != 23))
409                 return -EINVAL;
410         if (state->wss_enable != enable) {
411                 v4l_dbg(1, debug, client, "Turn WSS %s\n", enable ? "on" : "off");
412                 saa7127_write(client, 0x27, enable << 7);
413                 state->wss_enable = enable;
414         }
415         if (!enable)
416                 return 0;
417
418         saa7127_write(client, 0x26, data->data[0]);
419         saa7127_write(client, 0x27, 0x80 | (data->data[1] & 0x3f));
420         v4l_dbg(1, debug, client, "WSS mode: %s\n", wss_strs[data->data[0] & 0xf]);
421         state->wss_mode = (data->data[1] & 0x3f) << 8 | data->data[0];
422         return 0;
423 }
424
425 /* ----------------------------------------------------------------------- */
426
427 static int saa7127_set_video_enable(struct i2c_client *client, int enable)
428 {
429         struct saa7127_state *state = i2c_get_clientdata(client);
430
431         if (enable) {
432                 v4l_dbg(1, debug, client, "Enable Video Output\n");
433                 saa7127_write(client, 0x2d, state->reg_2d);
434                 saa7127_write(client, 0x61, state->reg_61);
435         } else {
436                 v4l_dbg(1, debug, client, "Disable Video Output\n");
437                 saa7127_write(client, 0x2d, (state->reg_2d & 0xf0));
438                 saa7127_write(client, 0x61, (state->reg_61 | 0xc0));
439         }
440         state->video_enable = enable;
441         return 0;
442 }
443
444 /* ----------------------------------------------------------------------- */
445
446 static int saa7127_set_std(struct i2c_client *client, v4l2_std_id std)
447 {
448         struct saa7127_state *state = i2c_get_clientdata(client);
449         const struct i2c_reg_value *inittab;
450
451         if (std & V4L2_STD_525_60) {
452                 v4l_dbg(1, debug, client, "Selecting 60 Hz video Standard\n");
453                 inittab = saa7127_init_config_60hz;
454                 state->reg_61 = SAA7127_60HZ_DAC_CONTROL;
455         } else {
456                 v4l_dbg(1, debug, client, "Selecting 50 Hz video Standard\n");
457                 inittab = saa7127_init_config_50hz;
458                 state->reg_61 = SAA7127_50HZ_DAC_CONTROL;
459         }
460
461         /* Write Table */
462         saa7127_write_inittab(client, inittab);
463         state->std = std;
464         return 0;
465 }
466
467 /* ----------------------------------------------------------------------- */
468
469 static int saa7127_set_output_type(struct i2c_client *client, int output)
470 {
471         struct saa7127_state *state = i2c_get_clientdata(client);
472
473         switch (output) {
474         case SAA7127_OUTPUT_TYPE_RGB:
475                 state->reg_2d = 0x0f;   /* RGB + CVBS (for sync) */
476                 state->reg_3a = 0x13;   /* by default switch YUV to RGB-matrix on */
477                 break;
478
479         case SAA7127_OUTPUT_TYPE_COMPOSITE:
480                 state->reg_2d = 0x08;   /* 00001000 CVBS only, RGB DAC's off (high impedance mode) */
481                 state->reg_3a = 0x13;   /* by default switch YUV to RGB-matrix on */
482                 break;
483
484         case SAA7127_OUTPUT_TYPE_SVIDEO:
485                 state->reg_2d = 0xff;   /* 11111111  croma -> R, luma -> CVBS + G + B */
486                 state->reg_3a = 0x13;   /* by default switch YUV to RGB-matrix on */
487                 break;
488
489         case SAA7127_OUTPUT_TYPE_YUV_V:
490                 state->reg_2d = 0x4f;   /* reg 2D = 01001111, all DAC's on, RGB + VBS */
491                 state->reg_3a = 0x0b;   /* reg 3A = 00001011, bypass RGB-matrix */
492                 break;
493
494         case SAA7127_OUTPUT_TYPE_YUV_C:
495                 state->reg_2d = 0x0f;   /* reg 2D = 00001111, all DAC's on, RGB + CVBS */
496                 state->reg_3a = 0x0b;   /* reg 3A = 00001011, bypass RGB-matrix */
497                 break;
498
499         case SAA7127_OUTPUT_TYPE_BOTH:
500                 state->reg_2d = 0xbf;
501                 state->reg_3a = 0x13;   /* by default switch YUV to RGB-matrix on */
502                 break;
503
504         default:
505                 return -EINVAL;
506         }
507         v4l_dbg(1, debug, client, "Selecting %s output type\n", output_strs[output]);
508
509         /* Configure Encoder */
510         saa7127_write(client, 0x2d, state->reg_2d);
511         saa7127_write(client, 0x3a, state->reg_3a | state->reg_3a_cb);
512         state->output_type = output;
513         return 0;
514 }
515
516 /* ----------------------------------------------------------------------- */
517
518 static int saa7127_set_input_type(struct i2c_client *client, int input)
519 {
520         struct saa7127_state *state = i2c_get_clientdata(client);
521
522         switch (input) {
523         case SAA7127_INPUT_TYPE_NORMAL: /* avia */
524                 v4l_dbg(1, debug, client, "Selecting Normal Encoder Input\n");
525                 state->reg_3a_cb = 0;
526                 break;
527
528         case SAA7127_INPUT_TYPE_TEST_IMAGE:     /* color bar */
529                 v4l_dbg(1, debug, client, "Selecting Color Bar generator\n");
530                 state->reg_3a_cb = 0x80;
531                 break;
532
533         default:
534                 return -EINVAL;
535         }
536         saa7127_write(client, 0x3a, state->reg_3a | state->reg_3a_cb);
537         state->input_type = input;
538         return 0;
539 }
540
541 /* ----------------------------------------------------------------------- */
542
543 static int saa7127_command(struct i2c_client *client,
544                            unsigned int cmd, void *arg)
545 {
546         struct saa7127_state *state = i2c_get_clientdata(client);
547         struct v4l2_format *fmt = arg;
548         struct v4l2_routing *route = arg;
549
550         switch (cmd) {
551         case VIDIOC_INT_S_STD_OUTPUT:
552                 if (state->std == *(v4l2_std_id *)arg)
553                         break;
554                 return saa7127_set_std(client, *(v4l2_std_id *)arg);
555
556         case VIDIOC_INT_G_STD_OUTPUT:
557                 *(v4l2_std_id *)arg = state->std;
558                 break;
559
560         case VIDIOC_INT_G_VIDEO_ROUTING:
561                 route->input = state->input_type;
562                 route->output = state->output_type;
563                 break;
564
565         case VIDIOC_INT_S_VIDEO_ROUTING:
566         {
567                 int rc = 0;
568
569                 if (state->input_type != route->input) {
570                         rc = saa7127_set_input_type(client, route->input);
571                 }
572                 if (rc == 0 && state->output_type != route->output) {
573                         rc = saa7127_set_output_type(client, route->output);
574                 }
575                 return rc;
576         }
577
578         case VIDIOC_STREAMON:
579         case VIDIOC_STREAMOFF:
580                 if (state->video_enable == (cmd == VIDIOC_STREAMON))
581                         break;
582                 return saa7127_set_video_enable(client, cmd == VIDIOC_STREAMON);
583
584         case VIDIOC_G_FMT:
585                 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
586                         return -EINVAL;
587
588                 memset(&fmt->fmt.sliced, 0, sizeof(fmt->fmt.sliced));
589                 if (state->vps_enable)
590                         fmt->fmt.sliced.service_lines[0][16] = V4L2_SLICED_VPS;
591                 if (state->wss_enable)
592                         fmt->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
593                 if (state->cc_enable) {
594                         fmt->fmt.sliced.service_lines[0][21] = V4L2_SLICED_CAPTION_525;
595                         fmt->fmt.sliced.service_lines[1][21] = V4L2_SLICED_CAPTION_525;
596                 }
597                 fmt->fmt.sliced.service_set =
598                         (state->vps_enable ? V4L2_SLICED_VPS : 0) |
599                         (state->wss_enable ? V4L2_SLICED_WSS_625 : 0) |
600                         (state->cc_enable ? V4L2_SLICED_CAPTION_525 : 0);
601                 break;
602
603         case VIDIOC_LOG_STATUS:
604                 v4l_info(client, "Standard: %s\n", (state->std & V4L2_STD_525_60) ? "60 Hz" : "50 Hz");
605                 v4l_info(client, "Input:    %s\n", state->input_type ?  "color bars" : "normal");
606                 v4l_info(client, "Output:   %s\n", state->video_enable ?
607                         output_strs[state->output_type] : "disabled");
608                 v4l_info(client, "WSS:      %s\n", state->wss_enable ?
609                         wss_strs[state->wss_mode] : "disabled");
610                 v4l_info(client, "VPS:      %s\n", state->vps_enable ? "enabled" : "disabled");
611                 v4l_info(client, "CC:       %s\n", state->cc_enable ? "enabled" : "disabled");
612                 break;
613
614 #ifdef CONFIG_VIDEO_ADV_DEBUG
615         case VIDIOC_DBG_G_REGISTER:
616         case VIDIOC_DBG_S_REGISTER:
617         {
618                 struct v4l2_register *reg = arg;
619
620                 if (!v4l2_chip_match_i2c_client(client, reg->match_type, reg->match_chip))
621                         return -EINVAL;
622                 if (!capable(CAP_SYS_ADMIN))
623                         return -EPERM;
624                 if (cmd == VIDIOC_DBG_G_REGISTER)
625                         reg->val = saa7127_read(client, reg->reg & 0xff);
626                 else
627                         saa7127_write(client, reg->reg & 0xff, reg->val & 0xff);
628                 break;
629         }
630 #endif
631
632         case VIDIOC_INT_S_VBI_DATA:
633         {
634                 struct v4l2_sliced_vbi_data *data = arg;
635
636                 switch (data->id) {
637                         case V4L2_SLICED_WSS_625:
638                                 return saa7127_set_wss(client, data);
639                         case V4L2_SLICED_VPS:
640                                 return saa7127_set_vps(client, data);
641                         case V4L2_SLICED_CAPTION_525:
642                                 if (data->field == 0)
643                                         return saa7127_set_cc(client, data);
644                                 return saa7127_set_xds(client, data);
645                         default:
646                                 return -EINVAL;
647                 }
648                 break;
649         }
650
651         case VIDIOC_G_CHIP_IDENT:
652                 return v4l2_chip_ident_i2c_client(client, arg, state->ident, 0);
653
654         default:
655                 return -EINVAL;
656         }
657         return 0;
658 }
659
660 /* ----------------------------------------------------------------------- */
661
662 static int saa7127_probe(struct i2c_client *client)
663 {
664         struct saa7127_state *state;
665         struct v4l2_sliced_vbi_data vbi = { 0, 0, 0, 0 };  /* set to disabled */
666         int read_result = 0;
667
668         /* Check if the adapter supports the needed features */
669         if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
670                 return -EIO;
671
672         snprintf(client->name, sizeof(client->name) - 1, "saa7127");
673
674         v4l_dbg(1, debug, client, "detecting saa7127 client on address 0x%x\n", client->addr << 1);
675
676         /* First test register 0: Bits 5-7 are a version ID (should be 0),
677            and bit 2 should also be 0.
678            This is rather general, so the second test is more specific and
679            looks at the 'ending point of burst in clock cycles' which is
680            0x1d after a reset and not expected to ever change. */
681         if ((saa7127_read(client, 0) & 0xe4) != 0 ||
682                         (saa7127_read(client, 0x29) & 0x3f) != 0x1d) {
683                 v4l_dbg(1, debug, client, "saa7127 not found\n");
684                 return -ENODEV;
685         }
686         state = kzalloc(sizeof(struct saa7127_state), GFP_KERNEL);
687
688         if (state == NULL) {
689                 return -ENOMEM;
690         }
691
692         i2c_set_clientdata(client, state);
693
694         /* Configure Encoder */
695
696         v4l_dbg(1, debug, client, "Configuring encoder\n");
697         saa7127_write_inittab(client, saa7127_init_config_common);
698         saa7127_set_std(client, V4L2_STD_NTSC);
699         saa7127_set_output_type(client, SAA7127_OUTPUT_TYPE_BOTH);
700         saa7127_set_vps(client, &vbi);
701         saa7127_set_wss(client, &vbi);
702         saa7127_set_cc(client, &vbi);
703         saa7127_set_xds(client, &vbi);
704         if (test_image == 1) {
705                 /* The Encoder has an internal Colorbar generator */
706                 /* This can be used for debugging */
707                 saa7127_set_input_type(client, SAA7127_INPUT_TYPE_TEST_IMAGE);
708         } else {
709                 saa7127_set_input_type(client, SAA7127_INPUT_TYPE_NORMAL);
710         }
711         saa7127_set_video_enable(client, 1);
712
713         /* Detect if it's an saa7129 */
714         read_result = saa7127_read(client, SAA7129_REG_FADE_KEY_COL2);
715         saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, 0xaa);
716         if (saa7127_read(client, SAA7129_REG_FADE_KEY_COL2) == 0xaa) {
717                 v4l_info(client, "saa7129 found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name);
718                 saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, read_result);
719                 saa7127_write_inittab(client, saa7129_init_config_extra);
720                 state->ident = V4L2_IDENT_SAA7129;
721         } else {
722                 v4l_info(client, "saa7127 found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name);
723                 state->ident = V4L2_IDENT_SAA7127;
724         }
725         return 0;
726 }
727
728 /* ----------------------------------------------------------------------- */
729
730 static int saa7127_remove(struct i2c_client *client)
731 {
732         /* Turn off TV output */
733         saa7127_set_video_enable(client, 0);
734         kfree(i2c_get_clientdata(client));
735         return 0;
736 }
737
738 /* ----------------------------------------------------------------------- */
739
740 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
741         .name = "saa7127",
742         .driverid = I2C_DRIVERID_SAA7127,
743         .command = saa7127_command,
744         .probe = saa7127_probe,
745         .remove = saa7127_remove,
746 };
747