linux/drivers/media/video/saa7191.c
<<
>>
Prefs
   1/*
   2 *  saa7191.c - Philips SAA7191 video decoder driver
   3 *
   4 *  Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
   5 *  Copyright (C) 2004,2005 Mikael Nousiainen <tmnousia@cc.hut.fi>
   6 *
   7 *  This program is free software; you can redistribute it and/or modify
   8 *  it under the terms of the GNU General Public License version 2 as
   9 *  published by the Free Software Foundation.
  10 */
  11
  12#include <linux/delay.h>
  13#include <linux/errno.h>
  14#include <linux/fs.h>
  15#include <linux/init.h>
  16#include <linux/kernel.h>
  17#include <linux/major.h>
  18#include <linux/module.h>
  19#include <linux/mm.h>
  20#include <linux/slab.h>
  21
  22#include <linux/videodev.h>
  23#include <linux/video_decoder.h>
  24#include <linux/i2c.h>
  25
  26#include "saa7191.h"
  27
  28#define SAA7191_MODULE_VERSION  "0.0.5"
  29
  30MODULE_DESCRIPTION("Philips SAA7191 video decoder driver");
  31MODULE_VERSION(SAA7191_MODULE_VERSION);
  32MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
  33MODULE_LICENSE("GPL");
  34
  35// #define SAA7191_DEBUG
  36
  37#ifdef SAA7191_DEBUG
  38#define dprintk(x...) printk("SAA7191: " x);
  39#else
  40#define dprintk(x...)
  41#endif
  42
  43#define SAA7191_SYNC_COUNT      30
  44#define SAA7191_SYNC_DELAY      100     /* milliseconds */
  45
  46struct saa7191 {
  47        struct i2c_client *client;
  48
  49        /* the register values are stored here as the actual
  50         * I2C-registers are write-only */
  51        u8 reg[25];
  52
  53        int input;
  54        int norm;
  55};
  56
  57static struct i2c_driver i2c_driver_saa7191;
  58
  59static const u8 initseq[] = {
  60        0,      /* Subaddress */
  61
  62        0x50,   /* (0x50) SAA7191_REG_IDEL */
  63
  64        /* 50 Hz signal timing */
  65        0x30,   /* (0x30) SAA7191_REG_HSYB */
  66        0x00,   /* (0x00) SAA7191_REG_HSYS */
  67        0xe8,   /* (0xe8) SAA7191_REG_HCLB */
  68        0xb6,   /* (0xb6) SAA7191_REG_HCLS */
  69        0xf4,   /* (0xf4) SAA7191_REG_HPHI */
  70
  71        /* control */
  72        SAA7191_LUMA_APER_1,    /* (0x01) SAA7191_REG_LUMA - CVBS mode */
  73        0x00,   /* (0x00) SAA7191_REG_HUEC */
  74        0xf8,   /* (0xf8) SAA7191_REG_CKTQ */
  75        0xf8,   /* (0xf8) SAA7191_REG_CKTS */
  76        0x90,   /* (0x90) SAA7191_REG_PLSE */
  77        0x90,   /* (0x90) SAA7191_REG_SESE */
  78        0x00,   /* (0x00) SAA7191_REG_GAIN */
  79        SAA7191_STDC_NFEN | SAA7191_STDC_HRMV,  /* (0x0c) SAA7191_REG_STDC
  80                                                 * - not SECAM,
  81                                                 * slow time constant */
  82        SAA7191_IOCK_OEDC | SAA7191_IOCK_OEHS | SAA7191_IOCK_OEVS
  83        | SAA7191_IOCK_OEDY,    /* (0x78) SAA7191_REG_IOCK
  84                                 * - chroma from CVBS, GPSW1 & 2 off */
  85        SAA7191_CTL3_AUFD | SAA7191_CTL3_SCEN | SAA7191_CTL3_OFTS
  86        | SAA7191_CTL3_YDEL0,   /* (0x99) SAA7191_REG_CTL3
  87                                 * - automatic field detection */
  88        0x00,   /* (0x00) SAA7191_REG_CTL4 */
  89        0x2c,   /* (0x2c) SAA7191_REG_CHCV - PAL nominal value */
  90        0x00,   /* unused */
  91        0x00,   /* unused */
  92
  93        /* 60 Hz signal timing */
  94        0x34,   /* (0x34) SAA7191_REG_HS6B */
  95        0x0a,   /* (0x0a) SAA7191_REG_HS6S */
  96        0xf4,   /* (0xf4) SAA7191_REG_HC6B */
  97        0xce,   /* (0xce) SAA7191_REG_HC6S */
  98        0xf4,   /* (0xf4) SAA7191_REG_HP6I */
  99};
 100
 101/* SAA7191 register handling */
 102
 103static u8 saa7191_read_reg(struct i2c_client *client,
 104                           u8 reg)
 105{
 106        return ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg];
 107}
 108
 109static int saa7191_read_status(struct i2c_client *client,
 110                               u8 *value)
 111{
 112        int ret;
 113
 114        ret = i2c_master_recv(client, value, 1);
 115        if (ret < 0) {
 116                printk(KERN_ERR "SAA7191: saa7191_read_status(): read failed\n");
 117                return ret;
 118        }
 119
 120        return 0;
 121}
 122
 123
 124static int saa7191_write_reg(struct i2c_client *client, u8 reg,
 125                             u8 value)
 126{
 127        ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg] = value;
 128        return i2c_smbus_write_byte_data(client, reg, value);
 129}
 130
 131/* the first byte of data must be the first subaddress number (register) */
 132static int saa7191_write_block(struct i2c_client *client,
 133                               u8 length, const u8 *data)
 134{
 135        int i;
 136        int ret;
 137
 138        struct saa7191 *decoder = (struct saa7191 *)i2c_get_clientdata(client);
 139        for (i = 0; i < (length - 1); i++) {
 140                decoder->reg[data[0] + i] = data[i + 1];
 141        }
 142
 143        ret = i2c_master_send(client, data, length);
 144        if (ret < 0) {
 145                printk(KERN_ERR "SAA7191: saa7191_write_block(): "
 146                       "write failed\n");
 147                return ret;
 148        }
 149
 150        return 0;
 151}
 152
 153/* Helper functions */
 154
 155static int saa7191_set_input(struct i2c_client *client, int input)
 156{
 157        struct saa7191 *decoder = i2c_get_clientdata(client);
 158        u8 luma = saa7191_read_reg(client, SAA7191_REG_LUMA);
 159        u8 iock = saa7191_read_reg(client, SAA7191_REG_IOCK);
 160        int err;
 161
 162        switch (input) {
 163        case SAA7191_INPUT_COMPOSITE: /* Set Composite input */
 164                iock &= ~(SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW1
 165                          | SAA7191_IOCK_GPSW2);
 166                /* Chrominance trap active */
 167                luma &= ~SAA7191_LUMA_BYPS;
 168                break;
 169        case SAA7191_INPUT_SVIDEO: /* Set S-Video input */
 170                iock |= SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW2;
 171                /* Chrominance trap bypassed */
 172                luma |= SAA7191_LUMA_BYPS;
 173                break;
 174        default:
 175                return -EINVAL;
 176        }
 177
 178        err = saa7191_write_reg(client, SAA7191_REG_LUMA, luma);
 179        if (err)
 180                return -EIO;
 181        err = saa7191_write_reg(client, SAA7191_REG_IOCK, iock);
 182        if (err)
 183                return -EIO;
 184
 185        decoder->input = input;
 186
 187        return 0;
 188}
 189
 190static int saa7191_set_norm(struct i2c_client *client, int norm)
 191{
 192        struct saa7191 *decoder = i2c_get_clientdata(client);
 193        u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
 194        u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
 195        u8 chcv = saa7191_read_reg(client, SAA7191_REG_CHCV);
 196        int err;
 197
 198        switch(norm) {
 199        case SAA7191_NORM_PAL:
 200                stdc &= ~SAA7191_STDC_SECS;
 201                ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
 202                chcv = SAA7191_CHCV_PAL;
 203                break;
 204        case SAA7191_NORM_NTSC:
 205                stdc &= ~SAA7191_STDC_SECS;
 206                ctl3 &= ~SAA7191_CTL3_AUFD;
 207                ctl3 |= SAA7191_CTL3_FSEL;
 208                chcv = SAA7191_CHCV_NTSC;
 209                break;
 210        case SAA7191_NORM_SECAM:
 211                stdc |= SAA7191_STDC_SECS;
 212                ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
 213                chcv = SAA7191_CHCV_PAL;
 214                break;
 215        default:
 216                return -EINVAL;
 217        }
 218
 219        err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
 220        if (err)
 221                return -EIO;
 222        err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc);
 223        if (err)
 224                return -EIO;
 225        err = saa7191_write_reg(client, SAA7191_REG_CHCV, chcv);
 226        if (err)
 227                return -EIO;
 228
 229        decoder->norm = norm;
 230
 231        dprintk("ctl3: %02x stdc: %02x chcv: %02x\n", ctl3,
 232                stdc, chcv);
 233        dprintk("norm: %d\n", norm);
 234
 235        return 0;
 236}
 237
 238static int saa7191_wait_for_signal(struct i2c_client *client, u8 *status)
 239{
 240        int i = 0;
 241
 242        dprintk("Checking for signal...\n");
 243
 244        for (i = 0; i < SAA7191_SYNC_COUNT; i++) {
 245                if (saa7191_read_status(client, status))
 246                        return -EIO;
 247
 248                if (((*status) & SAA7191_STATUS_HLCK) == 0) {
 249                        dprintk("Signal found\n");
 250                        return 0;
 251                }
 252
 253                msleep(SAA7191_SYNC_DELAY);
 254        }
 255
 256        dprintk("No signal\n");
 257
 258        return -EBUSY;
 259}
 260
 261static int saa7191_autodetect_norm_extended(struct i2c_client *client)
 262{
 263        u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
 264        u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
 265        u8 status;
 266        int err = 0;
 267
 268        dprintk("SAA7191 extended signal auto-detection...\n");
 269
 270        stdc &= ~SAA7191_STDC_SECS;
 271        ctl3 &= ~(SAA7191_CTL3_FSEL);
 272
 273        err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc);
 274        if (err) {
 275                err = -EIO;
 276                goto out;
 277        }
 278        err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
 279        if (err) {
 280                err = -EIO;
 281                goto out;
 282        }
 283
 284        ctl3 |= SAA7191_CTL3_AUFD;
 285        err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
 286        if (err) {
 287                err = -EIO;
 288                goto out;
 289        }
 290
 291        msleep(SAA7191_SYNC_DELAY);
 292
 293        err = saa7191_wait_for_signal(client, &status);
 294        if (err)
 295                goto out;
 296
 297        if (status & SAA7191_STATUS_FIDT) {
 298                /* 60Hz signal -> NTSC */
 299                dprintk("60Hz signal: NTSC\n");
 300                return saa7191_set_norm(client, SAA7191_NORM_NTSC);
 301        }
 302
 303        /* 50Hz signal */
 304        dprintk("50Hz signal: Trying PAL...\n");
 305
 306        /* try PAL first */
 307        err = saa7191_set_norm(client, SAA7191_NORM_PAL);
 308        if (err)
 309                goto out;
 310
 311        msleep(SAA7191_SYNC_DELAY);
 312
 313        err = saa7191_wait_for_signal(client, &status);
 314        if (err)
 315                goto out;
 316
 317        /* not 50Hz ? */
 318        if (status & SAA7191_STATUS_FIDT) {
 319                dprintk("No 50Hz signal\n");
 320                err = -EAGAIN;
 321                goto out;
 322        }
 323
 324        if (status & SAA7191_STATUS_CODE) {
 325                dprintk("PAL\n");
 326                return 0;
 327        }
 328
 329        dprintk("No color detected with PAL - Trying SECAM...\n");
 330
 331        /* no color detected ? -> try SECAM */
 332        err = saa7191_set_norm(client,
 333                               SAA7191_NORM_SECAM);
 334        if (err)
 335                goto out;
 336
 337        msleep(SAA7191_SYNC_DELAY);
 338
 339        err = saa7191_wait_for_signal(client, &status);
 340        if (err)
 341                goto out;
 342
 343        /* not 50Hz ? */
 344        if (status & SAA7191_STATUS_FIDT) {
 345                dprintk("No 50Hz signal\n");
 346                err = -EAGAIN;
 347                goto out;
 348        }
 349
 350        if (status & SAA7191_STATUS_CODE) {
 351                /* Color detected -> SECAM */
 352                dprintk("SECAM\n");
 353                return 0;
 354        }
 355
 356        dprintk("No color detected with SECAM - Going back to PAL.\n");
 357
 358        /* still no color detected ?
 359         * -> set norm back to PAL */
 360        err = saa7191_set_norm(client,
 361                               SAA7191_NORM_PAL);
 362        if (err)
 363                goto out;
 364
 365out:
 366        ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
 367        if (ctl3 & SAA7191_CTL3_AUFD) {
 368                ctl3 &= ~(SAA7191_CTL3_AUFD);
 369                err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
 370                if (err) {
 371                        err = -EIO;
 372                }
 373        }
 374
 375        return err;
 376}
 377
 378static int saa7191_autodetect_norm(struct i2c_client *client)
 379{
 380        u8 status;
 381
 382        dprintk("SAA7191 signal auto-detection...\n");
 383
 384        dprintk("Reading status...\n");
 385
 386        if (saa7191_read_status(client, &status))
 387                return -EIO;
 388
 389        dprintk("Checking for signal...\n");
 390
 391        /* no signal ? */
 392        if (status & SAA7191_STATUS_HLCK) {
 393                dprintk("No signal\n");
 394                return -EBUSY;
 395        }
 396
 397        dprintk("Signal found\n");
 398
 399        if (status & SAA7191_STATUS_FIDT) {
 400                /* 60hz signal -> NTSC */
 401                dprintk("NTSC\n");
 402                return saa7191_set_norm(client, SAA7191_NORM_NTSC);
 403        } else {
 404                /* 50hz signal -> PAL */
 405                dprintk("PAL\n");
 406                return saa7191_set_norm(client, SAA7191_NORM_PAL);
 407        }
 408}
 409
 410static int saa7191_get_control(struct i2c_client *client,
 411                               struct saa7191_control *ctrl)
 412{
 413        u8 reg;
 414        int ret = 0;
 415
 416        switch (ctrl->type) {
 417        case SAA7191_CONTROL_BANDPASS:
 418        case SAA7191_CONTROL_BANDPASS_WEIGHT:
 419        case SAA7191_CONTROL_CORING:
 420                reg = saa7191_read_reg(client, SAA7191_REG_LUMA);
 421                switch (ctrl->type) {
 422                case SAA7191_CONTROL_BANDPASS:
 423                        ctrl->value = ((s32)reg & SAA7191_LUMA_BPSS_MASK)
 424                                >> SAA7191_LUMA_BPSS_SHIFT;
 425                        break;
 426                case SAA7191_CONTROL_BANDPASS_WEIGHT:
 427                        ctrl->value = ((s32)reg & SAA7191_LUMA_APER_MASK)
 428                                >> SAA7191_LUMA_APER_SHIFT;
 429                        break;
 430                case SAA7191_CONTROL_CORING:
 431                        ctrl->value = ((s32)reg & SAA7191_LUMA_CORI_MASK)
 432                                >> SAA7191_LUMA_CORI_SHIFT;
 433                        break;
 434                }
 435                break;
 436        case SAA7191_CONTROL_FORCE_COLOUR:
 437        case SAA7191_CONTROL_CHROMA_GAIN:
 438                reg = saa7191_read_reg(client, SAA7191_REG_GAIN);
 439                if (ctrl->type == SAA7191_CONTROL_FORCE_COLOUR)
 440                        ctrl->value = ((s32)reg & SAA7191_GAIN_COLO) ? 1 : 0;
 441                else
 442                        ctrl->value = ((s32)reg & SAA7191_GAIN_LFIS_MASK)
 443                                >> SAA7191_GAIN_LFIS_SHIFT;
 444                break;
 445        case SAA7191_CONTROL_HUE:
 446                reg = saa7191_read_reg(client, SAA7191_REG_HUEC);
 447                if (reg < 0x80)
 448                        reg += 0x80;
 449                else
 450                        reg -= 0x80;
 451                ctrl->value = (s32)reg;
 452                break;
 453        case SAA7191_CONTROL_VTRC:
 454                reg = saa7191_read_reg(client, SAA7191_REG_STDC);
 455                ctrl->value = ((s32)reg & SAA7191_STDC_VTRC) ? 1 : 0;
 456                break;
 457        case SAA7191_CONTROL_LUMA_DELAY:
 458                reg = saa7191_read_reg(client, SAA7191_REG_CTL3);
 459                ctrl->value = ((s32)reg & SAA7191_CTL3_YDEL_MASK)
 460                        >> SAA7191_CTL3_YDEL_SHIFT;
 461                if (ctrl->value >= 4)
 462                        ctrl->value -= 8;
 463                break;
 464        case SAA7191_CONTROL_VNR:
 465                reg = saa7191_read_reg(client, SAA7191_REG_CTL4);
 466                ctrl->value = ((s32)reg & SAA7191_CTL4_VNOI_MASK)
 467                        >> SAA7191_CTL4_VNOI_SHIFT;
 468                break;
 469        default:
 470                ret = -EINVAL;
 471        }
 472
 473        return ret;
 474}
 475
 476static int saa7191_set_control(struct i2c_client *client,
 477                               struct saa7191_control *ctrl)
 478{
 479        u8 reg;
 480        int ret = 0;
 481
 482        switch (ctrl->type) {
 483        case SAA7191_CONTROL_BANDPASS:
 484        case SAA7191_CONTROL_BANDPASS_WEIGHT:
 485        case SAA7191_CONTROL_CORING:
 486                reg = saa7191_read_reg(client, SAA7191_REG_LUMA);
 487                switch (ctrl->type) {
 488                case SAA7191_CONTROL_BANDPASS:
 489                        reg &= ~SAA7191_LUMA_BPSS_MASK;
 490                        reg |= (ctrl->value << SAA7191_LUMA_BPSS_SHIFT)
 491                                & SAA7191_LUMA_BPSS_MASK;
 492                        break;
 493                case SAA7191_CONTROL_BANDPASS_WEIGHT:
 494                        reg &= ~SAA7191_LUMA_APER_MASK;
 495                        reg |= (ctrl->value << SAA7191_LUMA_APER_SHIFT)
 496                                & SAA7191_LUMA_APER_MASK;
 497                        break;
 498                case SAA7191_CONTROL_CORING:
 499                        reg &= ~SAA7191_LUMA_CORI_MASK;
 500                        reg |= (ctrl->value << SAA7191_LUMA_CORI_SHIFT)
 501                                & SAA7191_LUMA_CORI_MASK;
 502                        break;
 503                }
 504                ret = saa7191_write_reg(client, SAA7191_REG_LUMA, reg);
 505                break;
 506        case SAA7191_CONTROL_FORCE_COLOUR:
 507        case SAA7191_CONTROL_CHROMA_GAIN:
 508                reg = saa7191_read_reg(client, SAA7191_REG_GAIN);
 509                if (ctrl->type == SAA7191_CONTROL_FORCE_COLOUR) {
 510                        if (ctrl->value)
 511                                reg |= SAA7191_GAIN_COLO;
 512                        else
 513                                reg &= ~SAA7191_GAIN_COLO;
 514                } else {
 515                        reg &= ~SAA7191_GAIN_LFIS_MASK;
 516                        reg |= (ctrl->value << SAA7191_GAIN_LFIS_SHIFT)
 517                                & SAA7191_GAIN_LFIS_MASK;
 518                }
 519                ret = saa7191_write_reg(client, SAA7191_REG_GAIN, reg);
 520                break;
 521        case SAA7191_CONTROL_HUE:
 522                reg = ctrl->value & 0xff;
 523                if (reg < 0x80)
 524                        reg += 0x80;
 525                else
 526                        reg -= 0x80;
 527                ret = saa7191_write_reg(client, SAA7191_REG_HUEC, reg);
 528                break;
 529        case SAA7191_CONTROL_VTRC:
 530                reg = saa7191_read_reg(client, SAA7191_REG_STDC);
 531                if (ctrl->value)
 532                        reg |= SAA7191_STDC_VTRC;
 533                else
 534                        reg &= ~SAA7191_STDC_VTRC;
 535                ret = saa7191_write_reg(client, SAA7191_REG_STDC, reg);
 536                break;
 537        case SAA7191_CONTROL_LUMA_DELAY: {
 538                s32 value = ctrl->value;
 539                if (value < 0)
 540                        value += 8;
 541                reg = saa7191_read_reg(client, SAA7191_REG_CTL3);
 542                reg &= ~SAA7191_CTL3_YDEL_MASK;
 543                reg |= (value << SAA7191_CTL3_YDEL_SHIFT)
 544                        & SAA7191_CTL3_YDEL_MASK;
 545                ret = saa7191_write_reg(client, SAA7191_REG_CTL3, reg);
 546                break;
 547        }
 548        case SAA7191_CONTROL_VNR:
 549                reg = saa7191_read_reg(client, SAA7191_REG_CTL4);
 550                reg &= ~SAA7191_CTL4_VNOI_MASK;
 551                reg |= (ctrl->value << SAA7191_CTL4_VNOI_SHIFT)
 552                        & SAA7191_CTL4_VNOI_MASK;
 553                ret = saa7191_write_reg(client, SAA7191_REG_CTL4, reg);
 554                break;
 555        default:
 556                ret = -EINVAL;
 557        }
 558
 559        return ret;
 560}
 561
 562/* I2C-interface */
 563
 564static int saa7191_attach(struct i2c_adapter *adap, int addr, int kind)
 565{
 566        int err = 0;
 567        struct saa7191 *decoder;
 568        struct i2c_client *client;
 569
 570        printk(KERN_INFO "Philips SAA7191 driver version %s\n",
 571               SAA7191_MODULE_VERSION);
 572
 573        client = kzalloc(sizeof(*client), GFP_KERNEL);
 574        if (!client)
 575                return -ENOMEM;
 576        decoder = kzalloc(sizeof(*decoder), GFP_KERNEL);
 577        if (!decoder) {
 578                err = -ENOMEM;
 579                goto out_free_client;
 580        }
 581
 582        client->addr = addr;
 583        client->adapter = adap;
 584        client->driver = &i2c_driver_saa7191;
 585        client->flags = 0;
 586        strcpy(client->name, "saa7191 client");
 587        i2c_set_clientdata(client, decoder);
 588
 589        decoder->client = client;
 590
 591        err = i2c_attach_client(client);
 592        if (err)
 593                goto out_free_decoder;
 594
 595        err = saa7191_write_block(client, sizeof(initseq), initseq);
 596        if (err) {
 597                printk(KERN_ERR "SAA7191 initialization failed\n");
 598                goto out_detach_client;
 599        }
 600
 601        printk(KERN_INFO "SAA7191 initialized\n");
 602
 603        decoder->input = SAA7191_INPUT_COMPOSITE;
 604        decoder->norm = SAA7191_NORM_PAL;
 605
 606        err = saa7191_autodetect_norm(client);
 607        if (err && (err != -EBUSY)) {
 608                printk(KERN_ERR "SAA7191: Signal auto-detection failed\n");
 609        }
 610
 611        return 0;
 612
 613out_detach_client:
 614        i2c_detach_client(client);
 615out_free_decoder:
 616        kfree(decoder);
 617out_free_client:
 618        kfree(client);
 619        return err;
 620}
 621
 622static int saa7191_probe(struct i2c_adapter *adap)
 623{
 624        /* Always connected to VINO */
 625        if (adap->id == I2C_HW_SGI_VINO)
 626                return saa7191_attach(adap, SAA7191_ADDR, 0);
 627        /* Feel free to add probe here :-) */
 628        return -ENODEV;
 629}
 630
 631static int saa7191_detach(struct i2c_client *client)
 632{
 633        struct saa7191 *decoder = i2c_get_clientdata(client);
 634
 635        i2c_detach_client(client);
 636        kfree(decoder);
 637        kfree(client);
 638        return 0;
 639}
 640
 641static int saa7191_command(struct i2c_client *client, unsigned int cmd,
 642                           void *arg)
 643{
 644        struct saa7191 *decoder = i2c_get_clientdata(client);
 645
 646        switch (cmd) {
 647        case DECODER_GET_CAPABILITIES: {
 648                struct video_decoder_capability *cap = arg;
 649
 650                cap->flags  = VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC |
 651                              VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO;
 652                cap->inputs = (client->adapter->id == I2C_HW_SGI_VINO) ? 2 : 1;
 653                cap->outputs = 1;
 654                break;
 655        }
 656        case DECODER_GET_STATUS: {
 657                int *iarg = arg;
 658                u8 status;
 659                int res = 0;
 660
 661                if (saa7191_read_status(client, &status)) {
 662                        return -EIO;
 663                }
 664                if ((status & SAA7191_STATUS_HLCK) == 0)
 665                        res |= DECODER_STATUS_GOOD;
 666                if (status & SAA7191_STATUS_CODE)
 667                        res |= DECODER_STATUS_COLOR;
 668                switch (decoder->norm) {
 669                case SAA7191_NORM_NTSC:
 670                        res |= DECODER_STATUS_NTSC;
 671                        break;
 672                case SAA7191_NORM_PAL:
 673                        res |= DECODER_STATUS_PAL;
 674                        break;
 675                case SAA7191_NORM_SECAM:
 676                        res |= DECODER_STATUS_SECAM;
 677                        break;
 678                case SAA7191_NORM_AUTO:
 679                default:
 680                        if (status & SAA7191_STATUS_FIDT)
 681                                res |= DECODER_STATUS_NTSC;
 682                        else
 683                                res |= DECODER_STATUS_PAL;
 684                        break;
 685                }
 686                *iarg = res;
 687                break;
 688        }
 689        case DECODER_SET_NORM: {
 690                int *iarg = arg;
 691
 692                switch (*iarg) {
 693                case VIDEO_MODE_AUTO:
 694                        return saa7191_autodetect_norm(client);
 695                case VIDEO_MODE_PAL:
 696                        return saa7191_set_norm(client, SAA7191_NORM_PAL);
 697                case VIDEO_MODE_NTSC:
 698                        return saa7191_set_norm(client, SAA7191_NORM_NTSC);
 699                case VIDEO_MODE_SECAM:
 700                        return saa7191_set_norm(client, SAA7191_NORM_SECAM);
 701                default:
 702                        return -EINVAL;
 703                }
 704                break;
 705        }
 706        case DECODER_SET_INPUT: {
 707                int *iarg = arg;
 708
 709                switch (client->adapter->id) {
 710                case I2C_HW_SGI_VINO:
 711                        return saa7191_set_input(client, *iarg);
 712                default:
 713                        if (*iarg != 0)
 714                                return -EINVAL;
 715                }
 716                break;
 717        }
 718        case DECODER_SET_OUTPUT: {
 719                int *iarg = arg;
 720
 721                /* not much choice of outputs */
 722                if (*iarg != 0)
 723                        return -EINVAL;
 724                break;
 725        }
 726        case DECODER_ENABLE_OUTPUT: {
 727                /* Always enabled */
 728                break;
 729        }
 730        case DECODER_SET_PICTURE: {
 731                struct video_picture *pic = arg;
 732                unsigned val;
 733                int err;
 734
 735                val = (pic->hue >> 8) - 0x80;
 736
 737                err = saa7191_write_reg(client, SAA7191_REG_HUEC, val);
 738                if (err)
 739                        return -EIO;
 740
 741                break;
 742        }
 743        case DECODER_SAA7191_GET_STATUS: {
 744                struct saa7191_status *status = arg;
 745                u8 status_reg;
 746
 747                if (saa7191_read_status(client, &status_reg))
 748                        return -EIO;
 749
 750                status->signal = ((status_reg & SAA7191_STATUS_HLCK) == 0)
 751                        ? 1 : 0;
 752                status->signal_60hz = (status_reg & SAA7191_STATUS_FIDT)
 753                        ? 1 : 0;
 754                status->color = (status_reg & SAA7191_STATUS_CODE) ? 1 : 0;
 755
 756                status->input = decoder->input;
 757                status->norm = decoder->norm;
 758
 759                break;
 760        }
 761        case DECODER_SAA7191_SET_NORM: {
 762                int *norm = arg;
 763
 764                switch (*norm) {
 765                case SAA7191_NORM_AUTO:
 766                        return saa7191_autodetect_norm(client);
 767                case SAA7191_NORM_AUTO_EXT:
 768                        return saa7191_autodetect_norm_extended(client);
 769                default:
 770                        return saa7191_set_norm(client, *norm);
 771                }
 772        }
 773        case DECODER_SAA7191_GET_CONTROL: {
 774                return saa7191_get_control(client, arg);
 775        }
 776        case DECODER_SAA7191_SET_CONTROL: {
 777                return saa7191_set_control(client, arg);
 778        }
 779        default:
 780                return -EINVAL;
 781        }
 782
 783        return 0;
 784}
 785
 786static struct i2c_driver i2c_driver_saa7191 = {
 787        .driver = {
 788                .name   = "saa7191",
 789        },
 790        .id             = I2C_DRIVERID_SAA7191,
 791        .attach_adapter = saa7191_probe,
 792        .detach_client  = saa7191_detach,
 793        .command        = saa7191_command
 794};
 795
 796static int saa7191_init(void)
 797{
 798        return i2c_add_driver(&i2c_driver_saa7191);
 799}
 800
 801static void saa7191_exit(void)
 802{
 803        i2c_del_driver(&i2c_driver_saa7191);
 804}
 805
 806module_init(saa7191_init);
 807module_exit(saa7191_exit);
 808