linux/drivers/media/i2c/saa717x.c
<<
>>
Prefs
   1/*
   2 * saa717x - Philips SAA717xHL video decoder driver
   3 *
   4 * Based on the saa7115 driver
   5 *
   6 * Changes by Ohta Kyuma <alpha292@bremen.or.jp>
   7 *    - Apply to SAA717x,NEC uPD64031,uPD64083. (1/31/2004)
   8 *
   9 * Changes by T.Adachi (tadachi@tadachi-net.com)
  10 *    - support audio, video scaler etc, and checked the initialize sequence.
  11 *
  12 * Cleaned up by Hans Verkuil <hverkuil@xs4all.nl>
  13 *
  14 * Note: this is a reversed engineered driver based on captures from
  15 * the I2C bus under Windows. This chip is very similar to the saa7134,
  16 * though. Unfortunately, this driver is currently only working for NTSC.
  17 *
  18 * This program is free software; you can redistribute it and/or modify
  19 * it under the terms of the GNU General Public License as published by
  20 * the Free Software Foundation; either version 2 of the License, or
  21 * (at your option) any later version.
  22 *
  23 * This program is distributed in the hope that it will be useful,
  24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  26 * GNU General Public License for more details.
  27 */
  28
  29#include <linux/module.h>
  30#include <linux/kernel.h>
  31#include <linux/slab.h>
  32#include <linux/sched.h>
  33
  34#include <linux/videodev2.h>
  35#include <linux/i2c.h>
  36#include <media/v4l2-device.h>
  37#include <media/v4l2-ctrls.h>
  38
  39MODULE_DESCRIPTION("Philips SAA717x audio/video decoder driver");
  40MODULE_AUTHOR("K. Ohta, T. Adachi, Hans Verkuil");
  41MODULE_LICENSE("GPL");
  42
  43static int debug;
  44module_param(debug, int, 0644);
  45MODULE_PARM_DESC(debug, "Debug level (0-1)");
  46
  47/*
  48 * Generic i2c probe
  49 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
  50 */
  51
  52struct saa717x_state {
  53        struct v4l2_subdev sd;
  54        struct v4l2_ctrl_handler hdl;
  55        v4l2_std_id std;
  56        int input;
  57        int enable;
  58        int radio;
  59        int playback;
  60        int audio;
  61        int tuner_audio_mode;
  62        int audio_main_mute;
  63        int audio_main_vol_r;
  64        int audio_main_vol_l;
  65        u16 audio_main_bass;
  66        u16 audio_main_treble;
  67        u16 audio_main_volume;
  68        u16 audio_main_balance;
  69        int audio_input;
  70};
  71
  72static inline struct saa717x_state *to_state(struct v4l2_subdev *sd)
  73{
  74        return container_of(sd, struct saa717x_state, sd);
  75}
  76
  77static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
  78{
  79        return &container_of(ctrl->handler, struct saa717x_state, hdl)->sd;
  80}
  81
  82/* ----------------------------------------------------------------------- */
  83
  84/* for audio mode */
  85#define TUNER_AUDIO_MONO        0  /* LL */
  86#define TUNER_AUDIO_STEREO      1  /* LR */
  87#define TUNER_AUDIO_LANG1       2  /* LL */
  88#define TUNER_AUDIO_LANG2       3  /* RR */
  89
  90#define SAA717X_NTSC_WIDTH      (704)
  91#define SAA717X_NTSC_HEIGHT     (480)
  92
  93/* ----------------------------------------------------------------------- */
  94
  95static int saa717x_write(struct v4l2_subdev *sd, u32 reg, u32 value)
  96{
  97        struct i2c_client *client = v4l2_get_subdevdata(sd);
  98        struct i2c_adapter *adap = client->adapter;
  99        int fw_addr = reg == 0x454 || (reg >= 0x464 && reg <= 0x478) || reg == 0x480 || reg == 0x488;
 100        unsigned char mm1[6];
 101        struct i2c_msg msg;
 102
 103        msg.flags = 0;
 104        msg.addr = client->addr;
 105        mm1[0] = (reg >> 8) & 0xff;
 106        mm1[1] = reg & 0xff;
 107
 108        if (fw_addr) {
 109                mm1[4] = (value >> 16) & 0xff;
 110                mm1[3] = (value >> 8) & 0xff;
 111                mm1[2] = value & 0xff;
 112        } else {
 113                mm1[2] = value & 0xff;
 114        }
 115        msg.len = fw_addr ? 5 : 3; /* Long Registers have *only* three bytes! */
 116        msg.buf = mm1;
 117        v4l2_dbg(2, debug, sd, "wrote:  reg 0x%03x=%08x\n", reg, value);
 118        return i2c_transfer(adap, &msg, 1) == 1;
 119}
 120
 121static void saa717x_write_regs(struct v4l2_subdev *sd, u32 *data)
 122{
 123        while (data[0] || data[1]) {
 124                saa717x_write(sd, data[0], data[1]);
 125                data += 2;
 126        }
 127}
 128
 129static u32 saa717x_read(struct v4l2_subdev *sd, u32 reg)
 130{
 131        struct i2c_client *client = v4l2_get_subdevdata(sd);
 132        struct i2c_adapter *adap = client->adapter;
 133        int fw_addr = (reg >= 0x404 && reg <= 0x4b8) || reg == 0x528;
 134        unsigned char mm1[2];
 135        unsigned char mm2[4] = { 0, 0, 0, 0 };
 136        struct i2c_msg msgs[2];
 137        u32 value;
 138
 139        msgs[0].flags = 0;
 140        msgs[1].flags = I2C_M_RD;
 141        msgs[0].addr = msgs[1].addr = client->addr;
 142        mm1[0] = (reg >> 8) & 0xff;
 143        mm1[1] = reg & 0xff;
 144        msgs[0].len = 2;
 145        msgs[0].buf = mm1;
 146        msgs[1].len = fw_addr ? 3 : 1; /* Multibyte Registers contains *only* 3 bytes */
 147        msgs[1].buf = mm2;
 148        i2c_transfer(adap, msgs, 2);
 149
 150        if (fw_addr)
 151                value = (mm2[2] << 16)  | (mm2[1] << 8) | mm2[0];
 152        else
 153                value = mm2[0];
 154
 155        v4l2_dbg(2, debug, sd, "read:  reg 0x%03x=0x%08x\n", reg, value);
 156        return value;
 157}
 158
 159/* ----------------------------------------------------------------------- */
 160
 161static u32 reg_init_initialize[] =
 162{
 163        /* from linux driver */
 164        0x101, 0x008, /* Increment delay */
 165
 166        0x103, 0x000, /* Analog input control 2 */
 167        0x104, 0x090, /* Analog input control 3 */
 168        0x105, 0x090, /* Analog input control 4 */
 169        0x106, 0x0eb, /* Horizontal sync start */
 170        0x107, 0x0e0, /* Horizontal sync stop */
 171        0x109, 0x055, /* Luminance control */
 172
 173        0x10f, 0x02a, /* Chroma gain control */
 174        0x110, 0x000, /* Chroma control 2 */
 175
 176        0x114, 0x045, /* analog/ADC */
 177
 178        0x118, 0x040, /* RAW data gain */
 179        0x119, 0x080, /* RAW data offset */
 180
 181        0x044, 0x000, /* VBI horizontal input window start (L) TASK A */
 182        0x045, 0x000, /* VBI horizontal input window start (H) TASK A */
 183        0x046, 0x0cf, /* VBI horizontal input window stop (L) TASK A */
 184        0x047, 0x002, /* VBI horizontal input window stop (H) TASK A */
 185
 186        0x049, 0x000, /* VBI vertical input window start (H) TASK A */
 187
 188        0x04c, 0x0d0, /* VBI horizontal output length (L) TASK A */
 189        0x04d, 0x002, /* VBI horizontal output length (H) TASK A */
 190
 191        0x064, 0x080, /* Lumina brightness TASK A */
 192        0x065, 0x040, /* Luminance contrast TASK A */
 193        0x066, 0x040, /* Chroma saturation TASK A */
 194        /* 067H: Reserved */
 195        0x068, 0x000, /* VBI horizontal scaling increment (L) TASK A */
 196        0x069, 0x004, /* VBI horizontal scaling increment (H) TASK A */
 197        0x06a, 0x000, /* VBI phase offset TASK A */
 198
 199        0x06e, 0x000, /* Horizontal phase offset Luma TASK A */
 200        0x06f, 0x000, /* Horizontal phase offset Chroma TASK A */
 201
 202        0x072, 0x000, /* Vertical filter mode TASK A */
 203
 204        0x084, 0x000, /* VBI horizontal input window start (L) TAKS B */
 205        0x085, 0x000, /* VBI horizontal input window start (H) TAKS B */
 206        0x086, 0x0cf, /* VBI horizontal input window stop (L) TAKS B */
 207        0x087, 0x002, /* VBI horizontal input window stop (H) TAKS B */
 208
 209        0x089, 0x000, /* VBI vertical input window start (H) TAKS B */
 210
 211        0x08c, 0x0d0, /* VBI horizontal output length (L) TASK B */
 212        0x08d, 0x002, /* VBI horizontal output length (H) TASK B */
 213
 214        0x0a4, 0x080, /* Lumina brightness TASK B */
 215        0x0a5, 0x040, /* Luminance contrast TASK B */
 216        0x0a6, 0x040, /* Chroma saturation TASK B */
 217        /* 0A7H reserved */
 218        0x0a8, 0x000, /* VBI horizontal scaling increment (L) TASK B */
 219        0x0a9, 0x004, /* VBI horizontal scaling increment (H) TASK B */
 220        0x0aa, 0x000, /* VBI phase offset TASK B */
 221
 222        0x0ae, 0x000, /* Horizontal phase offset Luma TASK B */
 223        0x0af, 0x000, /*Horizontal phase offset Chroma TASK B */
 224
 225        0x0b2, 0x000, /* Vertical filter mode TASK B */
 226
 227        0x00c, 0x000, /* Start point GREEN path */
 228        0x00d, 0x000, /* Start point BLUE path */
 229        0x00e, 0x000, /* Start point RED path */
 230
 231        0x010, 0x010, /* GREEN path gamma curve --- */
 232        0x011, 0x020,
 233        0x012, 0x030,
 234        0x013, 0x040,
 235        0x014, 0x050,
 236        0x015, 0x060,
 237        0x016, 0x070,
 238        0x017, 0x080,
 239        0x018, 0x090,
 240        0x019, 0x0a0,
 241        0x01a, 0x0b0,
 242        0x01b, 0x0c0,
 243        0x01c, 0x0d0,
 244        0x01d, 0x0e0,
 245        0x01e, 0x0f0,
 246        0x01f, 0x0ff, /* --- GREEN path gamma curve */
 247
 248        0x020, 0x010, /* BLUE path gamma curve --- */
 249        0x021, 0x020,
 250        0x022, 0x030,
 251        0x023, 0x040,
 252        0x024, 0x050,
 253        0x025, 0x060,
 254        0x026, 0x070,
 255        0x027, 0x080,
 256        0x028, 0x090,
 257        0x029, 0x0a0,
 258        0x02a, 0x0b0,
 259        0x02b, 0x0c0,
 260        0x02c, 0x0d0,
 261        0x02d, 0x0e0,
 262        0x02e, 0x0f0,
 263        0x02f, 0x0ff, /* --- BLUE path gamma curve */
 264
 265        0x030, 0x010, /* RED path gamma curve --- */
 266        0x031, 0x020,
 267        0x032, 0x030,
 268        0x033, 0x040,
 269        0x034, 0x050,
 270        0x035, 0x060,
 271        0x036, 0x070,
 272        0x037, 0x080,
 273        0x038, 0x090,
 274        0x039, 0x0a0,
 275        0x03a, 0x0b0,
 276        0x03b, 0x0c0,
 277        0x03c, 0x0d0,
 278        0x03d, 0x0e0,
 279        0x03e, 0x0f0,
 280        0x03f, 0x0ff, /* --- RED path gamma curve */
 281
 282        0x109, 0x085, /* Luminance control  */
 283
 284        /**** from app start ****/
 285        0x584, 0x000, /* AGC gain control */
 286        0x585, 0x000, /* Program count */
 287        0x586, 0x003, /* Status reset */
 288        0x588, 0x0ff, /* Number of audio samples (L) */
 289        0x589, 0x00f, /* Number of audio samples (M) */
 290        0x58a, 0x000, /* Number of audio samples (H) */
 291        0x58b, 0x000, /* Audio select */
 292        0x58c, 0x010, /* Audio channel assign1 */
 293        0x58d, 0x032, /* Audio channel assign2 */
 294        0x58e, 0x054, /* Audio channel assign3 */
 295        0x58f, 0x023, /* Audio format */
 296        0x590, 0x000, /* SIF control */
 297
 298        0x595, 0x000, /* ?? */
 299        0x596, 0x000, /* ?? */
 300        0x597, 0x000, /* ?? */
 301
 302        0x464, 0x00, /* Digital input crossbar1 */
 303
 304        0x46c, 0xbbbb10, /* Digital output selection1-3 */
 305        0x470, 0x101010, /* Digital output selection4-6 */
 306
 307        0x478, 0x00, /* Sound feature control */
 308
 309        0x474, 0x18, /* Softmute control */
 310
 311        0x454, 0x0425b9, /* Sound Easy programming(reset) */
 312        0x454, 0x042539, /* Sound Easy programming(reset) */
 313
 314
 315        /**** common setting( of DVD play, including scaler commands) ****/
 316        0x042, 0x003, /* Data path configuration for VBI (TASK A) */
 317
 318        0x082, 0x003, /* Data path configuration for VBI (TASK B) */
 319
 320        0x108, 0x0f8, /* Sync control */
 321        0x2a9, 0x0fd, /* ??? */
 322        0x102, 0x089, /* select video input "mode 9" */
 323        0x111, 0x000, /* Mode/delay control */
 324
 325        0x10e, 0x00a, /* Chroma control 1 */
 326
 327        0x594, 0x002, /* SIF, analog I/O select */
 328
 329        0x454, 0x0425b9, /* Sound  */
 330        0x454, 0x042539,
 331
 332        0x111, 0x000,
 333        0x10e, 0x00a,
 334        0x464, 0x000,
 335        0x300, 0x000,
 336        0x301, 0x006,
 337        0x302, 0x000,
 338        0x303, 0x006,
 339        0x308, 0x040,
 340        0x309, 0x000,
 341        0x30a, 0x000,
 342        0x30b, 0x000,
 343        0x000, 0x002,
 344        0x001, 0x000,
 345        0x002, 0x000,
 346        0x003, 0x000,
 347        0x004, 0x033,
 348        0x040, 0x01d,
 349        0x041, 0x001,
 350        0x042, 0x004,
 351        0x043, 0x000,
 352        0x080, 0x01e,
 353        0x081, 0x001,
 354        0x082, 0x004,
 355        0x083, 0x000,
 356        0x190, 0x018,
 357        0x115, 0x000,
 358        0x116, 0x012,
 359        0x117, 0x018,
 360        0x04a, 0x011,
 361        0x08a, 0x011,
 362        0x04b, 0x000,
 363        0x08b, 0x000,
 364        0x048, 0x000,
 365        0x088, 0x000,
 366        0x04e, 0x012,
 367        0x08e, 0x012,
 368        0x058, 0x012,
 369        0x098, 0x012,
 370        0x059, 0x000,
 371        0x099, 0x000,
 372        0x05a, 0x003,
 373        0x09a, 0x003,
 374        0x05b, 0x001,
 375        0x09b, 0x001,
 376        0x054, 0x008,
 377        0x094, 0x008,
 378        0x055, 0x000,
 379        0x095, 0x000,
 380        0x056, 0x0c7,
 381        0x096, 0x0c7,
 382        0x057, 0x002,
 383        0x097, 0x002,
 384        0x0ff, 0x0ff,
 385        0x060, 0x001,
 386        0x0a0, 0x001,
 387        0x061, 0x000,
 388        0x0a1, 0x000,
 389        0x062, 0x000,
 390        0x0a2, 0x000,
 391        0x063, 0x000,
 392        0x0a3, 0x000,
 393        0x070, 0x000,
 394        0x0b0, 0x000,
 395        0x071, 0x004,
 396        0x0b1, 0x004,
 397        0x06c, 0x0e9,
 398        0x0ac, 0x0e9,
 399        0x06d, 0x003,
 400        0x0ad, 0x003,
 401        0x05c, 0x0d0,
 402        0x09c, 0x0d0,
 403        0x05d, 0x002,
 404        0x09d, 0x002,
 405        0x05e, 0x0f2,
 406        0x09e, 0x0f2,
 407        0x05f, 0x000,
 408        0x09f, 0x000,
 409        0x074, 0x000,
 410        0x0b4, 0x000,
 411        0x075, 0x000,
 412        0x0b5, 0x000,
 413        0x076, 0x000,
 414        0x0b6, 0x000,
 415        0x077, 0x000,
 416        0x0b7, 0x000,
 417        0x195, 0x008,
 418        0x0ff, 0x0ff,
 419        0x108, 0x0f8,
 420        0x111, 0x000,
 421        0x10e, 0x00a,
 422        0x2a9, 0x0fd,
 423        0x464, 0x001,
 424        0x454, 0x042135,
 425        0x598, 0x0e7,
 426        0x599, 0x07d,
 427        0x59a, 0x018,
 428        0x59c, 0x066,
 429        0x59d, 0x090,
 430        0x59e, 0x001,
 431        0x584, 0x000,
 432        0x585, 0x000,
 433        0x586, 0x003,
 434        0x588, 0x0ff,
 435        0x589, 0x00f,
 436        0x58a, 0x000,
 437        0x58b, 0x000,
 438        0x58c, 0x010,
 439        0x58d, 0x032,
 440        0x58e, 0x054,
 441        0x58f, 0x023,
 442        0x590, 0x000,
 443        0x595, 0x000,
 444        0x596, 0x000,
 445        0x597, 0x000,
 446        0x464, 0x000,
 447        0x46c, 0xbbbb10,
 448        0x470, 0x101010,
 449
 450
 451        0x478, 0x000,
 452        0x474, 0x018,
 453        0x454, 0x042135,
 454        0x598, 0x0e7,
 455        0x599, 0x07d,
 456        0x59a, 0x018,
 457        0x59c, 0x066,
 458        0x59d, 0x090,
 459        0x59e, 0x001,
 460        0x584, 0x000,
 461        0x585, 0x000,
 462        0x586, 0x003,
 463        0x588, 0x0ff,
 464        0x589, 0x00f,
 465        0x58a, 0x000,
 466        0x58b, 0x000,
 467        0x58c, 0x010,
 468        0x58d, 0x032,
 469        0x58e, 0x054,
 470        0x58f, 0x023,
 471        0x590, 0x000,
 472        0x595, 0x000,
 473        0x596, 0x000,
 474        0x597, 0x000,
 475        0x464, 0x000,
 476        0x46c, 0xbbbb10,
 477        0x470, 0x101010,
 478
 479        0x478, 0x000,
 480        0x474, 0x018,
 481        0x454, 0x042135,
 482        0x598, 0x0e7,
 483        0x599, 0x07d,
 484        0x59a, 0x018,
 485        0x59c, 0x066,
 486        0x59d, 0x090,
 487        0x59e, 0x001,
 488        0x584, 0x000,
 489        0x585, 0x000,
 490        0x586, 0x003,
 491        0x588, 0x0ff,
 492        0x589, 0x00f,
 493        0x58a, 0x000,
 494        0x58b, 0x000,
 495        0x58c, 0x010,
 496        0x58d, 0x032,
 497        0x58e, 0x054,
 498        0x58f, 0x023,
 499        0x590, 0x000,
 500        0x595, 0x000,
 501        0x596, 0x000,
 502        0x597, 0x000,
 503        0x464, 0x000,
 504        0x46c, 0xbbbb10,
 505        0x470, 0x101010,
 506        0x478, 0x000,
 507        0x474, 0x018,
 508        0x454, 0x042135,
 509        0x193, 0x000,
 510        0x300, 0x000,
 511        0x301, 0x006,
 512        0x302, 0x000,
 513        0x303, 0x006,
 514        0x308, 0x040,
 515        0x309, 0x000,
 516        0x30a, 0x000,
 517        0x30b, 0x000,
 518        0x000, 0x002,
 519        0x001, 0x000,
 520        0x002, 0x000,
 521        0x003, 0x000,
 522        0x004, 0x033,
 523        0x040, 0x01d,
 524        0x041, 0x001,
 525        0x042, 0x004,
 526        0x043, 0x000,
 527        0x080, 0x01e,
 528        0x081, 0x001,
 529        0x082, 0x004,
 530        0x083, 0x000,
 531        0x190, 0x018,
 532        0x115, 0x000,
 533        0x116, 0x012,
 534        0x117, 0x018,
 535        0x04a, 0x011,
 536        0x08a, 0x011,
 537        0x04b, 0x000,
 538        0x08b, 0x000,
 539        0x048, 0x000,
 540        0x088, 0x000,
 541        0x04e, 0x012,
 542        0x08e, 0x012,
 543        0x058, 0x012,
 544        0x098, 0x012,
 545        0x059, 0x000,
 546        0x099, 0x000,
 547        0x05a, 0x003,
 548        0x09a, 0x003,
 549        0x05b, 0x001,
 550        0x09b, 0x001,
 551        0x054, 0x008,
 552        0x094, 0x008,
 553        0x055, 0x000,
 554        0x095, 0x000,
 555        0x056, 0x0c7,
 556        0x096, 0x0c7,
 557        0x057, 0x002,
 558        0x097, 0x002,
 559        0x060, 0x001,
 560        0x0a0, 0x001,
 561        0x061, 0x000,
 562        0x0a1, 0x000,
 563        0x062, 0x000,
 564        0x0a2, 0x000,
 565        0x063, 0x000,
 566        0x0a3, 0x000,
 567        0x070, 0x000,
 568        0x0b0, 0x000,
 569        0x071, 0x004,
 570        0x0b1, 0x004,
 571        0x06c, 0x0e9,
 572        0x0ac, 0x0e9,
 573        0x06d, 0x003,
 574        0x0ad, 0x003,
 575        0x05c, 0x0d0,
 576        0x09c, 0x0d0,
 577        0x05d, 0x002,
 578        0x09d, 0x002,
 579        0x05e, 0x0f2,
 580        0x09e, 0x0f2,
 581        0x05f, 0x000,
 582        0x09f, 0x000,
 583        0x074, 0x000,
 584        0x0b4, 0x000,
 585        0x075, 0x000,
 586        0x0b5, 0x000,
 587        0x076, 0x000,
 588        0x0b6, 0x000,
 589        0x077, 0x000,
 590        0x0b7, 0x000,
 591        0x195, 0x008,
 592        0x598, 0x0e7,
 593        0x599, 0x07d,
 594        0x59a, 0x018,
 595        0x59c, 0x066,
 596        0x59d, 0x090,
 597        0x59e, 0x001,
 598        0x584, 0x000,
 599        0x585, 0x000,
 600        0x586, 0x003,
 601        0x588, 0x0ff,
 602        0x589, 0x00f,
 603        0x58a, 0x000,
 604        0x58b, 0x000,
 605        0x58c, 0x010,
 606        0x58d, 0x032,
 607        0x58e, 0x054,
 608        0x58f, 0x023,
 609        0x590, 0x000,
 610        0x595, 0x000,
 611        0x596, 0x000,
 612        0x597, 0x000,
 613        0x464, 0x000,
 614        0x46c, 0xbbbb10,
 615        0x470, 0x101010,
 616        0x478, 0x000,
 617        0x474, 0x018,
 618        0x454, 0x042135,
 619        0x193, 0x0a6,
 620        0x108, 0x0f8,
 621        0x042, 0x003,
 622        0x082, 0x003,
 623        0x454, 0x0425b9,
 624        0x454, 0x042539,
 625        0x193, 0x000,
 626        0x193, 0x0a6,
 627        0x464, 0x000,
 628
 629        0, 0
 630};
 631
 632/* Tuner */
 633static u32 reg_init_tuner_input[] = {
 634        0x108, 0x0f8, /* Sync control */
 635        0x111, 0x000, /* Mode/delay control */
 636        0x10e, 0x00a, /* Chroma control 1 */
 637        0, 0
 638};
 639
 640/* Composite */
 641static u32 reg_init_composite_input[] = {
 642        0x108, 0x0e8, /* Sync control */
 643        0x111, 0x000, /* Mode/delay control */
 644        0x10e, 0x04a, /* Chroma control 1 */
 645        0, 0
 646};
 647
 648/* S-Video */
 649static u32 reg_init_svideo_input[] = {
 650        0x108, 0x0e8, /* Sync control */
 651        0x111, 0x000, /* Mode/delay control */
 652        0x10e, 0x04a, /* Chroma control 1 */
 653        0, 0
 654};
 655
 656static u32 reg_set_audio_template[4][2] =
 657{
 658        { /* for MONO
 659                tadachi 6/29 DMA audio output select?
 660                Register 0x46c
 661                7-4: DMA2, 3-0: DMA1 ch. DMA4, DMA3 DMA2, DMA1
 662                0: MAIN left,  1: MAIN right
 663                2: AUX1 left,  3: AUX1 right
 664                4: AUX2 left,  5: AUX2 right
 665                6: DPL left,   7: DPL  right
 666                8: DPL center, 9: DPL surround
 667                A: monitor output, B: digital sense */
 668                0xbbbb00,
 669
 670                /* tadachi 6/29 DAC and I2S output select?
 671                   Register 0x470
 672                   7-4:DAC right ch. 3-0:DAC left ch.
 673                   I2S1 right,left  I2S2 right,left */
 674                0x00,
 675        },
 676        { /* for STEREO */
 677                0xbbbb10, 0x101010,
 678        },
 679        { /* for LANG1 */
 680                0xbbbb00, 0x00,
 681        },
 682        { /* for LANG2/SAP */
 683                0xbbbb11, 0x111111,
 684        }
 685};
 686
 687
 688/* Get detected audio flags (from saa7134 driver) */
 689static void get_inf_dev_status(struct v4l2_subdev *sd,
 690                int *dual_flag, int *stereo_flag)
 691{
 692        u32 reg_data3;
 693
 694        static char *stdres[0x20] = {
 695                [0x00] = "no standard detected",
 696                [0x01] = "B/G (in progress)",
 697                [0x02] = "D/K (in progress)",
 698                [0x03] = "M (in progress)",
 699
 700                [0x04] = "B/G A2",
 701                [0x05] = "B/G NICAM",
 702                [0x06] = "D/K A2 (1)",
 703                [0x07] = "D/K A2 (2)",
 704                [0x08] = "D/K A2 (3)",
 705                [0x09] = "D/K NICAM",
 706                [0x0a] = "L NICAM",
 707                [0x0b] = "I NICAM",
 708
 709                [0x0c] = "M Korea",
 710                [0x0d] = "M BTSC ",
 711                [0x0e] = "M EIAJ",
 712
 713                [0x0f] = "FM radio / IF 10.7 / 50 deemp",
 714                [0x10] = "FM radio / IF 10.7 / 75 deemp",
 715                [0x11] = "FM radio / IF sel / 50 deemp",
 716                [0x12] = "FM radio / IF sel / 75 deemp",
 717
 718                [0x13 ... 0x1e] = "unknown",
 719                [0x1f] = "??? [in progress]",
 720        };
 721
 722
 723        *dual_flag = *stereo_flag = 0;
 724
 725        /* (demdec status: 0x528) */
 726
 727        /* read current status */
 728        reg_data3 = saa717x_read(sd, 0x0528);
 729
 730        v4l2_dbg(1, debug, sd, "tvaudio thread status: 0x%x [%s%s%s]\n",
 731                reg_data3, stdres[reg_data3 & 0x1f],
 732                (reg_data3 & 0x000020) ? ",stereo" : "",
 733                (reg_data3 & 0x000040) ? ",dual"   : "");
 734        v4l2_dbg(1, debug, sd, "detailed status: "
 735                "%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s\n",
 736                (reg_data3 & 0x000080) ? " A2/EIAJ pilot tone "     : "",
 737                (reg_data3 & 0x000100) ? " A2/EIAJ dual "           : "",
 738                (reg_data3 & 0x000200) ? " A2/EIAJ stereo "         : "",
 739                (reg_data3 & 0x000400) ? " A2/EIAJ noise mute "     : "",
 740
 741                (reg_data3 & 0x000800) ? " BTSC/FM radio pilot "    : "",
 742                (reg_data3 & 0x001000) ? " SAP carrier "            : "",
 743                (reg_data3 & 0x002000) ? " BTSC stereo noise mute " : "",
 744                (reg_data3 & 0x004000) ? " SAP noise mute "         : "",
 745                (reg_data3 & 0x008000) ? " VDSP "                   : "",
 746
 747                (reg_data3 & 0x010000) ? " NICST "                  : "",
 748                (reg_data3 & 0x020000) ? " NICDU "                  : "",
 749                (reg_data3 & 0x040000) ? " NICAM muted "            : "",
 750                (reg_data3 & 0x080000) ? " NICAM reserve sound "    : "",
 751
 752                (reg_data3 & 0x100000) ? " init done "              : "");
 753
 754        if (reg_data3 & 0x000220) {
 755                v4l2_dbg(1, debug, sd, "ST!!!\n");
 756                *stereo_flag = 1;
 757        }
 758
 759        if (reg_data3 & 0x000140) {
 760                v4l2_dbg(1, debug, sd, "DUAL!!!\n");
 761                *dual_flag = 1;
 762        }
 763}
 764
 765/* regs write to set audio mode */
 766static void set_audio_mode(struct v4l2_subdev *sd, int audio_mode)
 767{
 768        v4l2_dbg(1, debug, sd, "writing registers to set audio mode by set %d\n",
 769                        audio_mode);
 770
 771        saa717x_write(sd, 0x46c, reg_set_audio_template[audio_mode][0]);
 772        saa717x_write(sd, 0x470, reg_set_audio_template[audio_mode][1]);
 773}
 774
 775/* write regs to set audio volume, bass and treble */
 776static int set_audio_regs(struct v4l2_subdev *sd,
 777                struct saa717x_state *decoder)
 778{
 779        u8 mute = 0xac; /* -84 dB */
 780        u32 val;
 781        unsigned int work_l, work_r;
 782
 783        /* set SIF analog I/O select */
 784        saa717x_write(sd, 0x0594, decoder->audio_input);
 785        v4l2_dbg(1, debug, sd, "set audio input %d\n",
 786                        decoder->audio_input);
 787
 788        /* normalize ( 65535 to 0 -> 24 to -40 (not -84)) */
 789        work_l = (min(65536 - decoder->audio_main_balance, 32768) * decoder->audio_main_volume) / 32768;
 790        work_r = (min(decoder->audio_main_balance, (u16)32768) * decoder->audio_main_volume) / 32768;
 791        decoder->audio_main_vol_l = (long)work_l * (24 - (-40)) / 65535 - 40;
 792        decoder->audio_main_vol_r = (long)work_r * (24 - (-40)) / 65535 - 40;
 793
 794        /* set main volume */
 795        /* main volume L[7-0],R[7-0],0x00  24=24dB,-83dB, -84(mute) */
 796        /*    def:0dB->6dB(MPG600GR) */
 797        /* if mute is on, set mute */
 798        if (decoder->audio_main_mute) {
 799                val = mute | (mute << 8);
 800        } else {
 801                val = (u8)decoder->audio_main_vol_l |
 802                        ((u8)decoder->audio_main_vol_r << 8);
 803        }
 804
 805        saa717x_write(sd, 0x480, val);
 806
 807        /* set bass and treble */
 808        val = decoder->audio_main_bass & 0x1f;
 809        val |= (decoder->audio_main_treble & 0x1f) << 5;
 810        saa717x_write(sd, 0x488, val);
 811        return 0;
 812}
 813
 814/********** scaling staff ***********/
 815static void set_h_prescale(struct v4l2_subdev *sd,
 816                int task, int prescale)
 817{
 818        static const struct {
 819                int xpsc;
 820                int xacl;
 821                int xc2_1;
 822                int xdcg;
 823                int vpfy;
 824        } vals[] = {
 825                /* XPSC XACL XC2_1 XDCG VPFY */
 826                {    1,   0,    0,    0,   0 },
 827                {    2,   2,    1,    2,   2 },
 828                {    3,   4,    1,    3,   2 },
 829                {    4,   8,    1,    4,   2 },
 830                {    5,   8,    1,    4,   2 },
 831                {    6,   8,    1,    4,   3 },
 832                {    7,   8,    1,    4,   3 },
 833                {    8,  15,    0,    4,   3 },
 834                {    9,  15,    0,    4,   3 },
 835                {   10,  16,    1,    5,   3 },
 836        };
 837        static const int count = ARRAY_SIZE(vals);
 838        int i, task_shift;
 839
 840        task_shift = task * 0x40;
 841        for (i = 0; i < count; i++)
 842                if (vals[i].xpsc == prescale)
 843                        break;
 844        if (i == count)
 845                return;
 846
 847        /* horizonal prescaling */
 848        saa717x_write(sd, 0x60 + task_shift, vals[i].xpsc);
 849        /* accumulation length */
 850        saa717x_write(sd, 0x61 + task_shift, vals[i].xacl);
 851        /* level control */
 852        saa717x_write(sd, 0x62 + task_shift,
 853                        (vals[i].xc2_1 << 3) | vals[i].xdcg);
 854        /*FIR prefilter control */
 855        saa717x_write(sd, 0x63 + task_shift,
 856                        (vals[i].vpfy << 2) | vals[i].vpfy);
 857}
 858
 859/********** scaling staff ***********/
 860static void set_v_scale(struct v4l2_subdev *sd, int task, int yscale)
 861{
 862        int task_shift;
 863
 864        task_shift = task * 0x40;
 865        /* Vertical scaling ratio (LOW) */
 866        saa717x_write(sd, 0x70 + task_shift, yscale & 0xff);
 867        /* Vertical scaling ratio (HI) */
 868        saa717x_write(sd, 0x71 + task_shift, yscale >> 8);
 869}
 870
 871static int saa717x_s_ctrl(struct v4l2_ctrl *ctrl)
 872{
 873        struct v4l2_subdev *sd = to_sd(ctrl);
 874        struct saa717x_state *state = to_state(sd);
 875
 876        switch (ctrl->id) {
 877        case V4L2_CID_BRIGHTNESS:
 878                saa717x_write(sd, 0x10a, ctrl->val);
 879                return 0;
 880
 881        case V4L2_CID_CONTRAST:
 882                saa717x_write(sd, 0x10b, ctrl->val);
 883                return 0;
 884
 885        case V4L2_CID_SATURATION:
 886                saa717x_write(sd, 0x10c, ctrl->val);
 887                return 0;
 888
 889        case V4L2_CID_HUE:
 890                saa717x_write(sd, 0x10d, ctrl->val);
 891                return 0;
 892
 893        case V4L2_CID_AUDIO_MUTE:
 894                state->audio_main_mute = ctrl->val;
 895                break;
 896
 897        case V4L2_CID_AUDIO_VOLUME:
 898                state->audio_main_volume = ctrl->val;
 899                break;
 900
 901        case V4L2_CID_AUDIO_BALANCE:
 902                state->audio_main_balance = ctrl->val;
 903                break;
 904
 905        case V4L2_CID_AUDIO_TREBLE:
 906                state->audio_main_treble = ctrl->val;
 907                break;
 908
 909        case V4L2_CID_AUDIO_BASS:
 910                state->audio_main_bass = ctrl->val;
 911                break;
 912
 913        default:
 914                return 0;
 915        }
 916        set_audio_regs(sd, state);
 917        return 0;
 918}
 919
 920static int saa717x_s_video_routing(struct v4l2_subdev *sd,
 921                                   u32 input, u32 output, u32 config)
 922{
 923        struct saa717x_state *decoder = to_state(sd);
 924        int is_tuner = input & 0x80;  /* tuner input flag */
 925
 926        input &= 0x7f;
 927
 928        v4l2_dbg(1, debug, sd, "decoder set input (%d)\n", input);
 929        /* inputs from 0-9 are available*/
 930        /* saa717x have mode0-mode9 but mode5 is reserved. */
 931        if (input > 9 || input == 5)
 932                return -EINVAL;
 933
 934        if (decoder->input != input) {
 935                int input_line = input;
 936
 937                decoder->input = input_line;
 938                v4l2_dbg(1, debug, sd,  "now setting %s input %d\n",
 939                                input_line >= 6 ? "S-Video" : "Composite",
 940                                input_line);
 941
 942                /* select mode */
 943                saa717x_write(sd, 0x102,
 944                                (saa717x_read(sd, 0x102) & 0xf0) |
 945                                input_line);
 946
 947                /* bypass chrominance trap for modes 6..9 */
 948                saa717x_write(sd, 0x109,
 949                                (saa717x_read(sd, 0x109) & 0x7f) |
 950                                (input_line < 6 ? 0x0 : 0x80));
 951
 952                /* change audio_mode */
 953                if (is_tuner) {
 954                        /* tuner */
 955                        set_audio_mode(sd, decoder->tuner_audio_mode);
 956                } else {
 957                        /* Force to STEREO mode if Composite or
 958                         * S-Video were chosen */
 959                        set_audio_mode(sd, TUNER_AUDIO_STEREO);
 960                }
 961                /* change initialize procedure (Composite/S-Video) */
 962                if (is_tuner)
 963                        saa717x_write_regs(sd, reg_init_tuner_input);
 964                else if (input_line >= 6)
 965                        saa717x_write_regs(sd, reg_init_svideo_input);
 966                else
 967                        saa717x_write_regs(sd, reg_init_composite_input);
 968        }
 969
 970        return 0;
 971}
 972
 973#ifdef CONFIG_VIDEO_ADV_DEBUG
 974static int saa717x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 975{
 976        reg->val = saa717x_read(sd, reg->reg);
 977        reg->size = 1;
 978        return 0;
 979}
 980
 981static int saa717x_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
 982{
 983        u16 addr = reg->reg & 0xffff;
 984        u8 val = reg->val & 0xff;
 985
 986        saa717x_write(sd, addr, val);
 987        return 0;
 988}
 989#endif
 990
 991static int saa717x_set_fmt(struct v4l2_subdev *sd,
 992                struct v4l2_subdev_pad_config *cfg,
 993                struct v4l2_subdev_format *format)
 994{
 995        struct v4l2_mbus_framefmt *fmt = &format->format;
 996        int prescale, h_scale, v_scale;
 997
 998        v4l2_dbg(1, debug, sd, "decoder set size\n");
 999
1000        if (format->pad || fmt->code != MEDIA_BUS_FMT_FIXED)
1001                return -EINVAL;
1002
1003        /* FIXME need better bounds checking here */
1004        if (fmt->width < 1 || fmt->width > 1440)
1005                return -EINVAL;
1006        if (fmt->height < 1 || fmt->height > 960)
1007                return -EINVAL;
1008
1009        fmt->field = V4L2_FIELD_INTERLACED;
1010        fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
1011
1012        if (format->which == V4L2_SUBDEV_FORMAT_TRY)
1013                return 0;
1014
1015        /* scaling setting */
1016        /* NTSC and interlace only */
1017        prescale = SAA717X_NTSC_WIDTH / fmt->width;
1018        if (prescale == 0)
1019                prescale = 1;
1020        h_scale = 1024 * SAA717X_NTSC_WIDTH / prescale / fmt->width;
1021        /* interlace */
1022        v_scale = 512 * 2 * SAA717X_NTSC_HEIGHT / fmt->height;
1023
1024        /* Horizontal prescaling etc */
1025        set_h_prescale(sd, 0, prescale);
1026        set_h_prescale(sd, 1, prescale);
1027
1028        /* Horizontal scaling increment */
1029        /* TASK A */
1030        saa717x_write(sd, 0x6C, (u8)(h_scale & 0xFF));
1031        saa717x_write(sd, 0x6D, (u8)((h_scale >> 8) & 0xFF));
1032        /* TASK B */
1033        saa717x_write(sd, 0xAC, (u8)(h_scale & 0xFF));
1034        saa717x_write(sd, 0xAD, (u8)((h_scale >> 8) & 0xFF));
1035
1036        /* Vertical prescaling etc */
1037        set_v_scale(sd, 0, v_scale);
1038        set_v_scale(sd, 1, v_scale);
1039
1040        /* set video output size */
1041        /* video number of pixels at output */
1042        /* TASK A */
1043        saa717x_write(sd, 0x5C, (u8)(fmt->width & 0xFF));
1044        saa717x_write(sd, 0x5D, (u8)((fmt->width >> 8) & 0xFF));
1045        /* TASK B */
1046        saa717x_write(sd, 0x9C, (u8)(fmt->width & 0xFF));
1047        saa717x_write(sd, 0x9D, (u8)((fmt->width >> 8) & 0xFF));
1048
1049        /* video number of lines at output */
1050        /* TASK A */
1051        saa717x_write(sd, 0x5E, (u8)(fmt->height & 0xFF));
1052        saa717x_write(sd, 0x5F, (u8)((fmt->height >> 8) & 0xFF));
1053        /* TASK B */
1054        saa717x_write(sd, 0x9E, (u8)(fmt->height & 0xFF));
1055        saa717x_write(sd, 0x9F, (u8)((fmt->height >> 8) & 0xFF));
1056        return 0;
1057}
1058
1059static int saa717x_s_radio(struct v4l2_subdev *sd)
1060{
1061        struct saa717x_state *decoder = to_state(sd);
1062
1063        decoder->radio = 1;
1064        return 0;
1065}
1066
1067static int saa717x_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
1068{
1069        struct saa717x_state *decoder = to_state(sd);
1070
1071        v4l2_dbg(1, debug, sd, "decoder set norm ");
1072        v4l2_dbg(1, debug, sd, "(not yet implemented)\n");
1073
1074        decoder->radio = 0;
1075        decoder->std = std;
1076        return 0;
1077}
1078
1079static int saa717x_s_audio_routing(struct v4l2_subdev *sd,
1080                                   u32 input, u32 output, u32 config)
1081{
1082        struct saa717x_state *decoder = to_state(sd);
1083
1084        if (input < 3) { /* FIXME! --tadachi */
1085                decoder->audio_input = input;
1086                v4l2_dbg(1, debug, sd,
1087                                "set decoder audio input to %d\n",
1088                                decoder->audio_input);
1089                set_audio_regs(sd, decoder);
1090                return 0;
1091        }
1092        return -ERANGE;
1093}
1094
1095static int saa717x_s_stream(struct v4l2_subdev *sd, int enable)
1096{
1097        struct saa717x_state *decoder = to_state(sd);
1098
1099        v4l2_dbg(1, debug, sd, "decoder %s output\n",
1100                        enable ? "enable" : "disable");
1101        decoder->enable = enable;
1102        saa717x_write(sd, 0x193, enable ? 0xa6 : 0x26);
1103        return 0;
1104}
1105
1106/* change audio mode */
1107static int saa717x_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner *vt)
1108{
1109        struct saa717x_state *decoder = to_state(sd);
1110        int audio_mode;
1111        char *mes[4] = {
1112                "MONO", "STEREO", "LANG1", "LANG2/SAP"
1113        };
1114
1115        audio_mode = TUNER_AUDIO_STEREO;
1116
1117        switch (vt->audmode) {
1118                case V4L2_TUNER_MODE_MONO:
1119                        audio_mode = TUNER_AUDIO_MONO;
1120                        break;
1121                case V4L2_TUNER_MODE_STEREO:
1122                        audio_mode = TUNER_AUDIO_STEREO;
1123                        break;
1124                case V4L2_TUNER_MODE_LANG2:
1125                        audio_mode = TUNER_AUDIO_LANG2;
1126                        break;
1127                case V4L2_TUNER_MODE_LANG1:
1128                        audio_mode = TUNER_AUDIO_LANG1;
1129                        break;
1130        }
1131
1132        v4l2_dbg(1, debug, sd, "change audio mode to %s\n",
1133                        mes[audio_mode]);
1134        decoder->tuner_audio_mode = audio_mode;
1135        /* The registers are not changed here. */
1136        /* See DECODER_ENABLE_OUTPUT section. */
1137        set_audio_mode(sd, decoder->tuner_audio_mode);
1138        return 0;
1139}
1140
1141static int saa717x_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1142{
1143        struct saa717x_state *decoder = to_state(sd);
1144        int dual_f, stereo_f;
1145
1146        if (decoder->radio)
1147                return 0;
1148        get_inf_dev_status(sd, &dual_f, &stereo_f);
1149
1150        v4l2_dbg(1, debug, sd, "DETECT==st:%d dual:%d\n",
1151                        stereo_f, dual_f);
1152
1153        /* mono */
1154        if ((dual_f == 0) && (stereo_f == 0)) {
1155                vt->rxsubchans = V4L2_TUNER_SUB_MONO;
1156                v4l2_dbg(1, debug, sd, "DETECT==MONO\n");
1157        }
1158
1159        /* stereo */
1160        if (stereo_f == 1) {
1161                if (vt->audmode == V4L2_TUNER_MODE_STEREO ||
1162                                vt->audmode == V4L2_TUNER_MODE_LANG1) {
1163                        vt->rxsubchans = V4L2_TUNER_SUB_STEREO;
1164                        v4l2_dbg(1, debug, sd, "DETECT==ST(ST)\n");
1165                } else {
1166                        vt->rxsubchans = V4L2_TUNER_SUB_MONO;
1167                        v4l2_dbg(1, debug, sd, "DETECT==ST(MONO)\n");
1168                }
1169        }
1170
1171        /* dual */
1172        if (dual_f == 1) {
1173                if (vt->audmode == V4L2_TUNER_MODE_LANG2) {
1174                        vt->rxsubchans = V4L2_TUNER_SUB_LANG2 | V4L2_TUNER_SUB_MONO;
1175                        v4l2_dbg(1, debug, sd, "DETECT==DUAL1\n");
1176                } else {
1177                        vt->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_MONO;
1178                        v4l2_dbg(1, debug, sd, "DETECT==DUAL2\n");
1179                }
1180        }
1181        return 0;
1182}
1183
1184static int saa717x_log_status(struct v4l2_subdev *sd)
1185{
1186        struct saa717x_state *state = to_state(sd);
1187
1188        v4l2_ctrl_handler_log_status(&state->hdl, sd->name);
1189        return 0;
1190}
1191
1192/* ----------------------------------------------------------------------- */
1193
1194static const struct v4l2_ctrl_ops saa717x_ctrl_ops = {
1195        .s_ctrl = saa717x_s_ctrl,
1196};
1197
1198static const struct v4l2_subdev_core_ops saa717x_core_ops = {
1199#ifdef CONFIG_VIDEO_ADV_DEBUG
1200        .g_register = saa717x_g_register,
1201        .s_register = saa717x_s_register,
1202#endif
1203        .log_status = saa717x_log_status,
1204};
1205
1206static const struct v4l2_subdev_tuner_ops saa717x_tuner_ops = {
1207        .g_tuner = saa717x_g_tuner,
1208        .s_tuner = saa717x_s_tuner,
1209        .s_radio = saa717x_s_radio,
1210};
1211
1212static const struct v4l2_subdev_video_ops saa717x_video_ops = {
1213        .s_std = saa717x_s_std,
1214        .s_routing = saa717x_s_video_routing,
1215        .s_stream = saa717x_s_stream,
1216};
1217
1218static const struct v4l2_subdev_audio_ops saa717x_audio_ops = {
1219        .s_routing = saa717x_s_audio_routing,
1220};
1221
1222static const struct v4l2_subdev_pad_ops saa717x_pad_ops = {
1223        .set_fmt = saa717x_set_fmt,
1224};
1225
1226static const struct v4l2_subdev_ops saa717x_ops = {
1227        .core = &saa717x_core_ops,
1228        .tuner = &saa717x_tuner_ops,
1229        .audio = &saa717x_audio_ops,
1230        .video = &saa717x_video_ops,
1231        .pad = &saa717x_pad_ops,
1232};
1233
1234/* ----------------------------------------------------------------------- */
1235
1236
1237/* i2c implementation */
1238
1239/* ----------------------------------------------------------------------- */
1240static int saa717x_probe(struct i2c_client *client,
1241                         const struct i2c_device_id *did)
1242{
1243        struct saa717x_state *decoder;
1244        struct v4l2_ctrl_handler *hdl;
1245        struct v4l2_subdev *sd;
1246        u8 id = 0;
1247        char *p = "";
1248
1249        /* Check if the adapter supports the needed features */
1250        if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1251                return -EIO;
1252
1253        decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
1254        if (decoder == NULL)
1255                return -ENOMEM;
1256
1257        sd = &decoder->sd;
1258        v4l2_i2c_subdev_init(sd, client, &saa717x_ops);
1259
1260        if (saa717x_write(sd, 0x5a4, 0xfe) &&
1261                        saa717x_write(sd, 0x5a5, 0x0f) &&
1262                        saa717x_write(sd, 0x5a6, 0x00) &&
1263                        saa717x_write(sd, 0x5a7, 0x01))
1264                id = saa717x_read(sd, 0x5a0);
1265        if (id != 0xc2 && id != 0x32 && id != 0xf2 && id != 0x6c) {
1266                v4l2_dbg(1, debug, sd, "saa717x not found (id=%02x)\n", id);
1267                return -ENODEV;
1268        }
1269        if (id == 0xc2)
1270                p = "saa7173";
1271        else if (id == 0x32)
1272                p = "saa7174A";
1273        else if (id == 0x6c)
1274                p = "saa7174HL";
1275        else
1276                p = "saa7171";
1277        v4l2_info(sd, "%s found @ 0x%x (%s)\n", p,
1278                        client->addr << 1, client->adapter->name);
1279
1280        hdl = &decoder->hdl;
1281        v4l2_ctrl_handler_init(hdl, 9);
1282        /* add in ascending ID order */
1283        v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
1284                        V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
1285        v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
1286                        V4L2_CID_CONTRAST, 0, 255, 1, 68);
1287        v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
1288                        V4L2_CID_SATURATION, 0, 255, 1, 64);
1289        v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
1290                        V4L2_CID_HUE, -128, 127, 1, 0);
1291        v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
1292                        V4L2_CID_AUDIO_VOLUME, 0, 65535, 65535 / 100, 42000);
1293        v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
1294                        V4L2_CID_AUDIO_BALANCE, 0, 65535, 65535 / 100, 32768);
1295        v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
1296                        V4L2_CID_AUDIO_BASS, -16, 15, 1, 0);
1297        v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
1298                        V4L2_CID_AUDIO_TREBLE, -16, 15, 1, 0);
1299        v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops,
1300                        V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
1301        sd->ctrl_handler = hdl;
1302        if (hdl->error) {
1303                int err = hdl->error;
1304
1305                v4l2_ctrl_handler_free(hdl);
1306                return err;
1307        }
1308
1309        decoder->std = V4L2_STD_NTSC;
1310        decoder->input = -1;
1311        decoder->enable = 1;
1312
1313        /* FIXME!! */
1314        decoder->playback = 0;  /* initially capture mode used */
1315        decoder->audio = 1; /* DECODER_AUDIO_48_KHZ */
1316
1317        decoder->audio_input = 2; /* FIXME!! */
1318
1319        decoder->tuner_audio_mode = TUNER_AUDIO_STEREO;
1320        /* set volume, bass and treble */
1321        decoder->audio_main_vol_l = 6;
1322        decoder->audio_main_vol_r = 6;
1323
1324        v4l2_dbg(1, debug, sd, "writing init values\n");
1325
1326        /* FIXME!! */
1327        saa717x_write_regs(sd, reg_init_initialize);
1328
1329        v4l2_ctrl_handler_setup(hdl);
1330
1331        set_current_state(TASK_INTERRUPTIBLE);
1332        schedule_timeout(2*HZ);
1333        return 0;
1334}
1335
1336static int saa717x_remove(struct i2c_client *client)
1337{
1338        struct v4l2_subdev *sd = i2c_get_clientdata(client);
1339
1340        v4l2_device_unregister_subdev(sd);
1341        v4l2_ctrl_handler_free(sd->ctrl_handler);
1342        return 0;
1343}
1344
1345/* ----------------------------------------------------------------------- */
1346
1347static const struct i2c_device_id saa717x_id[] = {
1348        { "saa717x", 0 },
1349        { }
1350};
1351MODULE_DEVICE_TABLE(i2c, saa717x_id);
1352
1353static struct i2c_driver saa717x_driver = {
1354        .driver = {
1355                .name   = "saa717x",
1356        },
1357        .probe          = saa717x_probe,
1358        .remove         = saa717x_remove,
1359        .id_table       = saa717x_id,
1360};
1361
1362module_i2c_driver(saa717x_driver);
1363