linux/drivers/media/video/bt819.c
<<
>>
Prefs
   1/*
   2 *  bt819 - BT819A VideoStream Decoder (Rockwell Part)
   3 *
   4 * Copyright (C) 1999 Mike Bernson <mike@mlb.org>
   5 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
   6 *
   7 * Modifications for LML33/DC10plus unified driver
   8 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
   9 *
  10 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
  11 *    - moved over to linux>=2.4.x i2c protocol (9/9/2002)
  12 *
  13 * This code was modify/ported from the saa7111 driver written
  14 * by Dave Perks.
  15 *
  16 * This program is free software; you can redistribute it and/or modify
  17 * it under the terms of the GNU General Public License as published by
  18 * the Free Software Foundation; either version 2 of the License, or
  19 * (at your option) any later version.
  20 *
  21 * This program is distributed in the hope that it will be useful,
  22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  24 * GNU General Public License for more details.
  25 *
  26 * You should have received a copy of the GNU General Public License
  27 * along with this program; if not, write to the Free Software
  28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  29 */
  30
  31#include <linux/module.h>
  32#include <linux/init.h>
  33#include <linux/delay.h>
  34#include <linux/errno.h>
  35#include <linux/fs.h>
  36#include <linux/kernel.h>
  37#include <linux/major.h>
  38#include <linux/slab.h>
  39#include <linux/mm.h>
  40#include <linux/signal.h>
  41#include <linux/types.h>
  42#include <linux/i2c.h>
  43#include <asm/io.h>
  44#include <asm/pgtable.h>
  45#include <asm/page.h>
  46#include <asm/uaccess.h>
  47
  48#include <linux/videodev.h>
  49#include <linux/video_decoder.h>
  50
  51
  52MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
  53MODULE_AUTHOR("Mike Bernson & Dave Perks");
  54MODULE_LICENSE("GPL");
  55
  56
  57#define I2C_NAME(s) (s)->name
  58
  59
  60static int debug = 0;
  61module_param(debug, int, 0);
  62MODULE_PARM_DESC(debug, "Debug level (0-1)");
  63
  64#define dprintk(num, format, args...) \
  65        do { \
  66                if (debug >= num) \
  67                        printk(format, ##args); \
  68        } while (0)
  69
  70/* ----------------------------------------------------------------------- */
  71
  72struct bt819 {
  73        unsigned char reg[32];
  74
  75        int initialized;
  76        int norm;
  77        int input;
  78        int enable;
  79        int bright;
  80        int contrast;
  81        int hue;
  82        int sat;
  83};
  84
  85struct timing {
  86        int hactive;
  87        int hdelay;
  88        int vactive;
  89        int vdelay;
  90        int hscale;
  91        int vscale;
  92};
  93
  94/* for values, see the bt819 datasheet */
  95static struct timing timing_data[] = {
  96        {864 - 24, 20, 625 - 2, 1, 0x0504, 0x0000},
  97        {858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000},
  98};
  99
 100#define   I2C_BT819        0x8a
 101
 102/* ----------------------------------------------------------------------- */
 103
 104static inline int
 105bt819_write (struct i2c_client *client,
 106             u8                 reg,
 107             u8                 value)
 108{
 109        struct bt819 *decoder = i2c_get_clientdata(client);
 110
 111        decoder->reg[reg] = value;
 112        return i2c_smbus_write_byte_data(client, reg, value);
 113}
 114
 115static inline int
 116bt819_setbit (struct i2c_client *client,
 117              u8                 reg,
 118              u8                 bit,
 119              u8                 value)
 120{
 121        struct bt819 *decoder = i2c_get_clientdata(client);
 122
 123        return bt819_write(client, reg,
 124                           (decoder->
 125                            reg[reg] & ~(1 << bit)) |
 126                            (value ? (1 << bit) : 0));
 127}
 128
 129static int
 130bt819_write_block (struct i2c_client *client,
 131                   const u8          *data,
 132                   unsigned int       len)
 133{
 134        int ret = -1;
 135        u8 reg;
 136
 137        /* the bt819 has an autoincrement function, use it if
 138         * the adapter understands raw I2C */
 139        if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
 140                /* do raw I2C, not smbus compatible */
 141                struct bt819 *decoder = i2c_get_clientdata(client);
 142                u8 block_data[32];
 143                int block_len;
 144
 145                while (len >= 2) {
 146                        block_len = 0;
 147                        block_data[block_len++] = reg = data[0];
 148                        do {
 149                                block_data[block_len++] =
 150                                    decoder->reg[reg++] = data[1];
 151                                len -= 2;
 152                                data += 2;
 153                        } while (len >= 2 && data[0] == reg &&
 154                                 block_len < 32);
 155                        if ((ret = i2c_master_send(client, block_data,
 156                                                   block_len)) < 0)
 157                                break;
 158                }
 159        } else {
 160                /* do some slow I2C emulation kind of thing */
 161                while (len >= 2) {
 162                        reg = *data++;
 163                        if ((ret = bt819_write(client, reg, *data++)) < 0)
 164                                break;
 165                        len -= 2;
 166                }
 167        }
 168
 169        return ret;
 170}
 171
 172static inline int
 173bt819_read (struct i2c_client *client,
 174            u8                 reg)
 175{
 176        return i2c_smbus_read_byte_data(client, reg);
 177}
 178
 179static int
 180bt819_init (struct i2c_client *client)
 181{
 182        struct bt819 *decoder = i2c_get_clientdata(client);
 183
 184        static unsigned char init[] = {
 185                //0x1f, 0x00,     /* Reset */
 186                0x01, 0x59,     /* 0x01 input format */
 187                0x02, 0x00,     /* 0x02 temporal decimation */
 188                0x03, 0x12,     /* 0x03 Cropping msb */
 189                0x04, 0x16,     /* 0x04 Vertical Delay, lsb */
 190                0x05, 0xe0,     /* 0x05 Vertical Active lsb */
 191                0x06, 0x80,     /* 0x06 Horizontal Delay lsb */
 192                0x07, 0xd0,     /* 0x07 Horizontal Active lsb */
 193                0x08, 0x00,     /* 0x08 Horizontal Scaling msb */
 194                0x09, 0xf8,     /* 0x09 Horizontal Scaling lsb */
 195                0x0a, 0x00,     /* 0x0a Brightness control */
 196                0x0b, 0x30,     /* 0x0b Miscellaneous control */
 197                0x0c, 0xd8,     /* 0x0c Luma Gain lsb */
 198                0x0d, 0xfe,     /* 0x0d Chroma Gain (U) lsb */
 199                0x0e, 0xb4,     /* 0x0e Chroma Gain (V) msb */
 200                0x0f, 0x00,     /* 0x0f Hue control */
 201                0x12, 0x04,     /* 0x12 Output Format */
 202                0x13, 0x20,     /* 0x13 Vertial Scaling msb 0x00
 203                                           chroma comb OFF, line drop scaling, interlace scaling
 204                                           BUG? Why does turning the chroma comb on fuck up color?
 205                                           Bug in the bt819 stepping on my board?
 206                                        */
 207                0x14, 0x00,     /* 0x14 Vertial Scaling lsb */
 208                0x16, 0x07,     /* 0x16 Video Timing Polarity
 209                                           ACTIVE=active low
 210                                           FIELD: high=odd,
 211                                           vreset=active high,
 212                                           hreset=active high */
 213                0x18, 0x68,     /* 0x18 AGC Delay */
 214                0x19, 0x5d,     /* 0x19 Burst Gate Delay */
 215                0x1a, 0x80,     /* 0x1a ADC Interface */
 216        };
 217
 218        struct timing *timing = &timing_data[decoder->norm];
 219
 220        init[0x03 * 2 - 1] =
 221            (((timing->vdelay >> 8) & 0x03) << 6) | (((timing->
 222                                                       vactive >> 8) &
 223                                                      0x03) << 4) |
 224            (((timing->hdelay >> 8) & 0x03) << 2) | ((timing->
 225                                                      hactive >> 8) &
 226                                                     0x03);
 227        init[0x04 * 2 - 1] = timing->vdelay & 0xff;
 228        init[0x05 * 2 - 1] = timing->vactive & 0xff;
 229        init[0x06 * 2 - 1] = timing->hdelay & 0xff;
 230        init[0x07 * 2 - 1] = timing->hactive & 0xff;
 231        init[0x08 * 2 - 1] = timing->hscale >> 8;
 232        init[0x09 * 2 - 1] = timing->hscale & 0xff;
 233        /* 0x15 in array is address 0x19 */
 234        init[0x15 * 2 - 1] = (decoder->norm == 0) ? 115 : 93;   /* Chroma burst delay */
 235        /* reset */
 236        bt819_write(client, 0x1f, 0x00);
 237        mdelay(1);
 238
 239        /* init */
 240        return bt819_write_block(client, init, sizeof(init));
 241
 242}
 243
 244/* ----------------------------------------------------------------------- */
 245
 246static int
 247bt819_command (struct i2c_client *client,
 248               unsigned int       cmd,
 249               void              *arg)
 250{
 251        int temp;
 252
 253        struct bt819 *decoder = i2c_get_clientdata(client);
 254
 255        if (!decoder->initialized) {    // First call to bt819_init could be
 256                bt819_init(client);     // without #FRST = 0
 257                decoder->initialized = 1;
 258        }
 259
 260        switch (cmd) {
 261
 262        case 0:
 263                /* This is just for testing!!! */
 264                bt819_init(client);
 265                break;
 266
 267        case DECODER_GET_CAPABILITIES:
 268        {
 269                struct video_decoder_capability *cap = arg;
 270
 271                cap->flags = VIDEO_DECODER_PAL |
 272                             VIDEO_DECODER_NTSC |
 273                             VIDEO_DECODER_AUTO |
 274                             VIDEO_DECODER_CCIR;
 275                cap->inputs = 8;
 276                cap->outputs = 1;
 277        }
 278                break;
 279
 280        case DECODER_GET_STATUS:
 281        {
 282                int *iarg = arg;
 283                int status;
 284                int res;
 285
 286                status = bt819_read(client, 0x00);
 287                res = 0;
 288                if ((status & 0x80)) {
 289                        res |= DECODER_STATUS_GOOD;
 290                }
 291                switch (decoder->norm) {
 292                case VIDEO_MODE_NTSC:
 293                        res |= DECODER_STATUS_NTSC;
 294                        break;
 295                case VIDEO_MODE_PAL:
 296                        res |= DECODER_STATUS_PAL;
 297                        break;
 298                default:
 299                case VIDEO_MODE_AUTO:
 300                        if ((status & 0x10)) {
 301                                res |= DECODER_STATUS_PAL;
 302                        } else {
 303                                res |= DECODER_STATUS_NTSC;
 304                        }
 305                        break;
 306                }
 307                res |= DECODER_STATUS_COLOR;
 308                *iarg = res;
 309
 310                dprintk(1, KERN_INFO "%s: get status %x\n", I2C_NAME(client),
 311                        *iarg);
 312        }
 313                break;
 314
 315        case DECODER_SET_NORM:
 316        {
 317                int *iarg = arg;
 318                struct timing *timing = NULL;
 319
 320                dprintk(1, KERN_INFO "%s: set norm %x\n", I2C_NAME(client),
 321                        *iarg);
 322
 323                switch (*iarg) {
 324                case VIDEO_MODE_NTSC:
 325                        bt819_setbit(client, 0x01, 0, 1);
 326                        bt819_setbit(client, 0x01, 1, 0);
 327                        bt819_setbit(client, 0x01, 5, 0);
 328                        bt819_write(client, 0x18, 0x68);
 329                        bt819_write(client, 0x19, 0x5d);
 330                        //bt819_setbit(client, 0x1a,  5, 1);
 331                        timing = &timing_data[VIDEO_MODE_NTSC];
 332                        break;
 333                case VIDEO_MODE_PAL:
 334                        bt819_setbit(client, 0x01, 0, 1);
 335                        bt819_setbit(client, 0x01, 1, 1);
 336                        bt819_setbit(client, 0x01, 5, 1);
 337                        bt819_write(client, 0x18, 0x7f);
 338                        bt819_write(client, 0x19, 0x72);
 339                        //bt819_setbit(client, 0x1a,  5, 0);
 340                        timing = &timing_data[VIDEO_MODE_PAL];
 341                        break;
 342                case VIDEO_MODE_AUTO:
 343                        bt819_setbit(client, 0x01, 0, 0);
 344                        bt819_setbit(client, 0x01, 1, 0);
 345                        break;
 346                default:
 347                        dprintk(1,
 348                                KERN_ERR
 349                                "%s: unsupported norm %d\n",
 350                                I2C_NAME(client), *iarg);
 351                        return -EINVAL;
 352                }
 353
 354                if (timing) {
 355                        bt819_write(client, 0x03,
 356                                    (((timing->vdelay >> 8) & 0x03) << 6) |
 357                                    (((timing->vactive >> 8) & 0x03) << 4) |
 358                                    (((timing->hdelay >> 8) & 0x03) << 2) |
 359                                     ((timing->hactive >> 8) & 0x03) );
 360                        bt819_write(client, 0x04, timing->vdelay & 0xff);
 361                        bt819_write(client, 0x05, timing->vactive & 0xff);
 362                        bt819_write(client, 0x06, timing->hdelay & 0xff);
 363                        bt819_write(client, 0x07, timing->hactive & 0xff);
 364                        bt819_write(client, 0x08, (timing->hscale >> 8) & 0xff);
 365                        bt819_write(client, 0x09, timing->hscale & 0xff);
 366                }
 367
 368                decoder->norm = *iarg;
 369        }
 370                break;
 371
 372        case DECODER_SET_INPUT:
 373        {
 374                int *iarg = arg;
 375
 376                dprintk(1, KERN_INFO "%s: set input %x\n", I2C_NAME(client),
 377                        *iarg);
 378
 379                if (*iarg < 0 || *iarg > 7) {
 380                        return -EINVAL;
 381                }
 382
 383                if (decoder->input != *iarg) {
 384                        decoder->input = *iarg;
 385                        /* select mode */
 386                        if (decoder->input == 0) {
 387                                bt819_setbit(client, 0x0b, 6, 0);
 388                                bt819_setbit(client, 0x1a, 1, 1);
 389                        } else {
 390                                bt819_setbit(client, 0x0b, 6, 1);
 391                                bt819_setbit(client, 0x1a, 1, 0);
 392                        }
 393                }
 394        }
 395                break;
 396
 397        case DECODER_SET_OUTPUT:
 398        {
 399                int *iarg = arg;
 400
 401                dprintk(1, KERN_INFO "%s: set output %x\n", I2C_NAME(client),
 402                        *iarg);
 403
 404                /* not much choice of outputs */
 405                if (*iarg != 0) {
 406                        return -EINVAL;
 407                }
 408        }
 409                break;
 410
 411        case DECODER_ENABLE_OUTPUT:
 412        {
 413                int *iarg = arg;
 414                int enable = (*iarg != 0);
 415
 416                dprintk(1, KERN_INFO "%s: enable output %x\n",
 417                        I2C_NAME(client), *iarg);
 418
 419                if (decoder->enable != enable) {
 420                        decoder->enable = enable;
 421
 422                        if (decoder->enable) {
 423                                bt819_setbit(client, 0x16, 7, 0);
 424                        } else {
 425                                bt819_setbit(client, 0x16, 7, 1);
 426                        }
 427                }
 428        }
 429                break;
 430
 431        case DECODER_SET_PICTURE:
 432        {
 433                struct video_picture *pic = arg;
 434
 435                dprintk(1,
 436                        KERN_INFO
 437                        "%s: set picture brightness %d contrast %d colour %d\n",
 438                        I2C_NAME(client), pic->brightness, pic->contrast,
 439                        pic->colour);
 440
 441
 442                if (decoder->bright != pic->brightness) {
 443                        /* We want -128 to 127 we get 0-65535 */
 444                        decoder->bright = pic->brightness;
 445                        bt819_write(client, 0x0a,
 446                                    (decoder->bright >> 8) - 128);
 447                }
 448
 449                if (decoder->contrast != pic->contrast) {
 450                        /* We want 0 to 511 we get 0-65535 */
 451                        decoder->contrast = pic->contrast;
 452                        bt819_write(client, 0x0c,
 453                                    (decoder->contrast >> 7) & 0xff);
 454                        bt819_setbit(client, 0x0b, 2,
 455                                     ((decoder->contrast >> 15) & 0x01));
 456                }
 457
 458                if (decoder->sat != pic->colour) {
 459                        /* We want 0 to 511 we get 0-65535 */
 460                        decoder->sat = pic->colour;
 461                        bt819_write(client, 0x0d,
 462                                    (decoder->sat >> 7) & 0xff);
 463                        bt819_setbit(client, 0x0b, 1,
 464                                     ((decoder->sat >> 15) & 0x01));
 465
 466                        temp = (decoder->sat * 201) / 237;
 467                        bt819_write(client, 0x0e, (temp >> 7) & 0xff);
 468                        bt819_setbit(client, 0x0b, 0, (temp >> 15) & 0x01);
 469                }
 470
 471                if (decoder->hue != pic->hue) {
 472                        /* We want -128 to 127 we get 0-65535 */
 473                        decoder->hue = pic->hue;
 474                        bt819_write(client, 0x0f,
 475                                    128 - (decoder->hue >> 8));
 476                }
 477        }
 478                break;
 479
 480        default:
 481                return -EINVAL;
 482        }
 483
 484        return 0;
 485}
 486
 487/* ----------------------------------------------------------------------- */
 488
 489/*
 490 * Generic i2c probe
 491 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
 492 */
 493static unsigned short normal_i2c[] = {
 494        I2C_BT819 >> 1,
 495        I2C_CLIENT_END,
 496};
 497
 498static unsigned short ignore = I2C_CLIENT_END;
 499
 500static struct i2c_client_address_data addr_data = {
 501        .normal_i2c             = normal_i2c,
 502        .probe                  = &ignore,
 503        .ignore                 = &ignore,
 504};
 505
 506static struct i2c_driver i2c_driver_bt819;
 507
 508static int
 509bt819_detect_client (struct i2c_adapter *adapter,
 510                     int                 address,
 511                     int                 kind)
 512{
 513        int i, id;
 514        struct bt819 *decoder;
 515        struct i2c_client *client;
 516
 517        dprintk(1,
 518                KERN_INFO
 519                "saa7111.c: detecting bt819 client on address 0x%x\n",
 520                address << 1);
 521
 522        /* Check if the adapter supports the needed features */
 523        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 524                return 0;
 525
 526        client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
 527        if (client == 0)
 528                return -ENOMEM;
 529        client->addr = address;
 530        client->adapter = adapter;
 531        client->driver = &i2c_driver_bt819;
 532
 533        decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL);
 534        if (decoder == NULL) {
 535                kfree(client);
 536                return -ENOMEM;
 537        }
 538        decoder->norm = VIDEO_MODE_NTSC;
 539        decoder->input = 0;
 540        decoder->enable = 1;
 541        decoder->bright = 32768;
 542        decoder->contrast = 32768;
 543        decoder->hue = 32768;
 544        decoder->sat = 32768;
 545        decoder->initialized = 0;
 546        i2c_set_clientdata(client, decoder);
 547
 548        id = bt819_read(client, 0x17);
 549        switch (id & 0xf0) {
 550        case 0x70:
 551                strlcpy(I2C_NAME(client), "bt819a", sizeof(I2C_NAME(client)));
 552                break;
 553        case 0x60:
 554                strlcpy(I2C_NAME(client), "bt817a", sizeof(I2C_NAME(client)));
 555                break;
 556        case 0x20:
 557                strlcpy(I2C_NAME(client), "bt815a", sizeof(I2C_NAME(client)));
 558                break;
 559        default:
 560                dprintk(1,
 561                        KERN_ERR
 562                        "bt819: unknown chip version 0x%x (ver 0x%x)\n",
 563                        id & 0xf0, id & 0x0f);
 564                kfree(decoder);
 565                kfree(client);
 566                return 0;
 567        }
 568
 569        i = i2c_attach_client(client);
 570        if (i) {
 571                kfree(client);
 572                kfree(decoder);
 573                return i;
 574        }
 575
 576        i = bt819_init(client);
 577        if (i < 0) {
 578                dprintk(1, KERN_ERR "%s_attach: init status %d\n",
 579                        I2C_NAME(client), i);
 580        } else {
 581                dprintk(1,
 582                        KERN_INFO
 583                        "%s_attach: chip version 0x%x at address 0x%x\n",
 584                        I2C_NAME(client), id & 0x0f,
 585                        client->addr << 1);
 586        }
 587
 588        return 0;
 589}
 590
 591static int
 592bt819_attach_adapter (struct i2c_adapter *adapter)
 593{
 594        return i2c_probe(adapter, &addr_data, &bt819_detect_client);
 595}
 596
 597static int
 598bt819_detach_client (struct i2c_client *client)
 599{
 600        struct bt819 *decoder = i2c_get_clientdata(client);
 601        int err;
 602
 603        err = i2c_detach_client(client);
 604        if (err) {
 605                return err;
 606        }
 607
 608        kfree(decoder);
 609        kfree(client);
 610
 611        return 0;
 612}
 613
 614/* ----------------------------------------------------------------------- */
 615
 616static struct i2c_driver i2c_driver_bt819 = {
 617        .driver = {
 618                .name = "bt819",
 619        },
 620
 621        .id = I2C_DRIVERID_BT819,
 622
 623        .attach_adapter = bt819_attach_adapter,
 624        .detach_client = bt819_detach_client,
 625        .command = bt819_command,
 626};
 627
 628static int __init
 629bt819_init_module (void)
 630{
 631        return i2c_add_driver(&i2c_driver_bt819);
 632}
 633
 634static void __exit
 635bt819_exit (void)
 636{
 637        i2c_del_driver(&i2c_driver_bt819);
 638}
 639
 640module_init(bt819_init_module);
 641module_exit(bt819_exit);
 642