2 * saa7127 - Philips SAA7127/SAA7129 video encoder driver
4 * Copyright (C) 2003 Roy Bulter <rbulter@hetnet.nl>
6 * Based on SAA7126 video encoder driver by Gillem & Andreas Oberritter
8 * Copyright (C) 2000-2001 Gillem <htoa@gmx.net>
9 * Copyright (C) 2002 Andreas Oberritter <obi@saftware.de>
11 * Based on Stadis 4:2:2 MPEG-2 Decoder Driver by Nathan Laredo
13 * Copyright (C) 1999 Nathan Laredo <laredo@gnu.org>
15 * This driver is designed for the Hauppauge 250/350 Linux driver
16 * from the ivtv Project
18 * Copyright (C) 2003 Kevin Thayer <nufan_wfk@yahoo.com>
20 * Dual output support:
21 * Copyright (C) 2004 Eric Varsanyi
23 * NTSC Tuning and 7.5 IRE Setup
24 * Copyright (C) 2004 Chris Kennedy <c@groovy.org>
26 * VBI additions & cleanup:
27 * Copyright (C) 2004, 2005 Hans Verkuil <hverkuil@xs4all.nl>
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
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.
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.
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.
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>
60 static int test_image = 0;
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)");
72 #define saa7127_dbg(fmt, arg...) \
75 printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
76 i2c_adapter_id(client->adapter), client->addr , ## arg); \
79 /* High volume debug. Use with care. */
80 #define saa7127_dbg_highvol(fmt, arg...) \
83 printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
84 i2c_adapter_id(client->adapter), client->addr , ## arg); \
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)
94 static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
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
154 **********************************************************************
156 * Arrays with configuration parameters for the SAA7127
158 **********************************************************************
161 struct i2c_reg_value {
166 static const struct i2c_reg_value saa7129_init_config_extra[] = {
167 { SAA7127_REG_OUTPUT_PORT_CONTROL, 0x38 },
168 { SAA7127_REG_VTRIG, 0xfa },
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 },
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 },
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 },
250 /* Enumeration for the Supported input types */
251 enum saa7127_input_type {
252 SAA7127_INPUT_TYPE_NORMAL,
253 SAA7127_INPUT_TYPE_TEST_IMAGE
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
267 **********************************************************************
269 * Encoder Struct, holds the configuration state of the encoder
271 **********************************************************************
274 struct saa7127_state {
276 enum v4l2_chip_ident ident;
277 enum saa7127_input_type input_type;
278 enum saa7127_output_type output_type;
290 u8 reg_3a_cb; /* colorbar bit */
294 static const char * const output_strs[] =
296 "S-Video + Composite",
304 static const char * const wss_strs[] = {
306 "letterbox 14:9 center",
307 "letterbox 14:9 top",
309 "letterbox 16:9 top",
312 "16:9 full format anamorphic"
316 "letterbox 16:9 center",
318 "letterbox >16:9 center",
319 "14:9 full format center",
323 /* ----------------------------------------------------------------------- */
325 static int saa7127_read(struct i2c_client *client, u8 reg)
327 return i2c_smbus_read_byte_data(client, reg);
330 /* ----------------------------------------------------------------------- */
332 static int saa7127_write(struct i2c_client *client, u8 reg, u8 val)
336 for (i = 0; i < 3; i++) {
337 if (i2c_smbus_write_byte_data(client, reg, val) == 0)
340 saa7127_err("I2C Write Problem\n");
344 /* ----------------------------------------------------------------------- */
346 static int saa7127_write_inittab(struct i2c_client *client,
347 const struct i2c_reg_value *regs)
349 while (regs->reg != 0) {
350 saa7127_write(client, regs->reg, regs->value);
356 /* ----------------------------------------------------------------------- */
358 static int saa7127_set_vps(struct i2c_client *client, struct v4l2_sliced_vbi_data *data)
360 struct saa7127_state *state = i2c_get_clientdata(client);
361 int enable = (data->line != 0);
363 if (enable && (data->field != 0 || data->line != 16))
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;
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],
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]);
390 /* ----------------------------------------------------------------------- */
392 static int saa7127_set_cc(struct i2c_client *client, struct v4l2_sliced_vbi_data *data)
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);
398 if (enable && (data->field != 0 || data->line != 21))
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;
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);
416 /* ----------------------------------------------------------------------- */
418 static int saa7127_set_xds(struct i2c_client *client, struct v4l2_sliced_vbi_data *data)
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);
424 if (enable && (data->field != 1 || data->line != 21))
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;
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;
442 /* ----------------------------------------------------------------------- */
444 static int saa7127_set_wss(struct i2c_client *client, struct v4l2_sliced_vbi_data *data)
446 struct saa7127_state *state = i2c_get_clientdata(client);
447 int enable = (data->line != 0);
449 if (enable && (data->field != 0 || data->line != 23))
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;
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];
466 /* ----------------------------------------------------------------------- */
468 static int saa7127_set_video_enable(struct i2c_client *client, int enable)
470 struct saa7127_state *state = i2c_get_clientdata(client);
473 saa7127_dbg("Enable Video Output\n");
474 saa7127_write(client, 0x2d, state->reg_2d);
475 saa7127_write(client, 0x61, state->reg_61);
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));
481 state->video_enable = enable;
485 /* ----------------------------------------------------------------------- */
487 static int saa7127_set_std(struct i2c_client *client, v4l2_std_id std)
489 struct saa7127_state *state = i2c_get_clientdata(client);
490 const struct i2c_reg_value *inittab;
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;
497 saa7127_dbg("Selecting 50 Hz video Standard\n");
498 inittab = saa7127_init_config_50hz;
499 state->reg_61 = SAA7127_50HZ_DAC_CONTROL;
503 saa7127_write_inittab(client, inittab);
508 /* ----------------------------------------------------------------------- */
510 static int saa7127_set_output_type(struct i2c_client *client, int output)
512 struct saa7127_state *state = i2c_get_clientdata(client);
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 */
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 */
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 */
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 */
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 */
540 case SAA7127_OUTPUT_TYPE_BOTH:
541 state->reg_2d = 0xbf;
542 state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */
548 saa7127_dbg("Selecting %s output type\n", output_strs[output]);
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;
557 /* ----------------------------------------------------------------------- */
559 static int saa7127_set_input_type(struct i2c_client *client, int input)
561 struct saa7127_state *state = i2c_get_clientdata(client);
564 case SAA7127_INPUT_TYPE_NORMAL: /* avia */
565 saa7127_dbg("Selecting Normal Encoder Input\n");
566 state->reg_3a_cb = 0;
569 case SAA7127_INPUT_TYPE_TEST_IMAGE: /* color bar */
570 saa7127_dbg("Selecting Color Bar generator\n");
571 state->reg_3a_cb = 0x80;
577 saa7127_write(client, 0x3a, state->reg_3a | state->reg_3a_cb);
578 state->input_type = input;
582 /* ----------------------------------------------------------------------- */
584 static int saa7127_command(struct i2c_client *client,
585 unsigned int cmd, void *arg)
587 struct saa7127_state *state = i2c_get_clientdata(client);
588 struct v4l2_format *fmt = arg;
593 if (state->std == *(v4l2_std_id *)arg)
595 return saa7127_set_std(client, *(v4l2_std_id *)arg);
598 *(v4l2_std_id *)arg = state->std;
602 if (state->input_type == *iarg)
604 return saa7127_set_input_type(client, *iarg);
606 case VIDIOC_S_OUTPUT:
607 if (state->output_type == *iarg)
609 return saa7127_set_output_type(client, *iarg);
611 case VIDIOC_STREAMON:
612 case VIDIOC_STREAMOFF:
613 if (state->video_enable == (cmd == VIDIOC_STREAMON))
615 return saa7127_set_video_enable(client, cmd == VIDIOC_STREAMON);
618 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
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;
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);
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");
647 #ifdef CONFIG_VIDEO_ADV_DEBUG
648 case VIDIOC_INT_G_REGISTER:
650 struct v4l2_register *reg = arg;
652 if (reg->i2c_id != I2C_DRIVERID_SAA7127)
654 reg->val = saa7127_read(client, reg->reg & 0xff);
658 case VIDIOC_INT_S_REGISTER:
660 struct v4l2_register *reg = arg;
662 if (reg->i2c_id != I2C_DRIVERID_SAA7127)
664 if (!capable(CAP_SYS_ADMIN))
666 saa7127_write(client, reg->reg & 0xff, reg->val & 0xff);
671 case VIDIOC_INT_S_VBI_DATA:
673 struct v4l2_sliced_vbi_data *data = arg;
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);
690 case VIDIOC_INT_G_CHIP_IDENT:
691 *(enum v4l2_chip_ident *)arg = state->ident;
700 /* ----------------------------------------------------------------------- */
702 struct i2c_driver i2c_driver_saa7127;
704 /* ----------------------------------------------------------------------- */
706 static int saa7127_attach(struct i2c_adapter *adapter, int address, int kind)
708 struct i2c_client *client;
709 struct saa7127_state *state;
710 struct v4l2_sliced_vbi_data vbi = { 0, 0, 0, 0 }; /* set to disabled */
713 /* Check if the adapter supports the needed features */
714 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
717 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
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");
728 saa7127_dbg("detecting saa7127 client on address 0x%x\n", address << 1);
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");
741 state = kmalloc(sizeof(struct saa7127_state), GFP_KERNEL);
748 i2c_set_clientdata(client, state);
749 memset(state, 0, sizeof(struct saa7127_state));
751 /* Configure Encoder */
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);
766 saa7127_set_input_type(client, SAA7127_INPUT_TYPE_NORMAL);
768 saa7127_set_video_enable(client, 1);
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;
779 saa7127_info("saa7127 found @ 0x%x (%s)\n", address << 1, adapter->name);
780 state->ident = V4L2_IDENT_SAA7127;
783 i2c_attach_client(client);
788 /* ----------------------------------------------------------------------- */
790 static int saa7127_probe(struct i2c_adapter *adapter)
792 #ifdef I2C_CLASS_TV_ANALOG
793 if (adapter->class & I2C_CLASS_TV_ANALOG)
795 if (adapter->id == I2C_HW_B_BT848)
797 return i2c_probe(adapter, &addr_data, saa7127_attach);
801 /* ----------------------------------------------------------------------- */
803 static int saa7127_detach(struct i2c_client *client)
805 struct saa7127_state *state = i2c_get_clientdata(client);
808 /* Turn off TV output */
809 saa7127_set_video_enable(client, 0);
811 err = i2c_detach_client(client);
822 /* ----------------------------------------------------------------------- */
824 struct i2c_driver i2c_driver_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,
835 /* ----------------------------------------------------------------------- */
837 static int __init saa7127_init_module(void)
839 return i2c_add_driver(&i2c_driver_saa7127);
842 /* ----------------------------------------------------------------------- */
844 static void __exit saa7127_cleanup_module(void)
846 i2c_del_driver(&i2c_driver_saa7127);
849 /* ----------------------------------------------------------------------- */
851 module_init(saa7127_init_module);
852 module_exit(saa7127_cleanup_module);