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