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