OSDN Git Service

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