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