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