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