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