Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

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