linux/drivers/media/video/bt856.c
<<
>>
Prefs
   1/*
   2 * bt856 - BT856A Digital Video Encoder (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 * This code was modify/ported from the saa7111 driver written
  11 * by Dave Perks.
  12 *
  13 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
  14 *   - moved over to linux>=2.4.x i2c protocol (9/9/2002)
  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 <linux/video_encoder.h>
  44#include <asm/io.h>
  45#include <asm/pgtable.h>
  46#include <asm/page.h>
  47#include <asm/uaccess.h>
  48
  49#include <linux/videodev.h>
  50
  51MODULE_DESCRIPTION("Brooktree-856A video encoder driver");
  52MODULE_AUTHOR("Mike Bernson & Dave Perks");
  53MODULE_LICENSE("GPL");
  54
  55
  56#define I2C_NAME(s) (s)->name
  57
  58
  59static int debug = 0;
  60module_param(debug, int, 0);
  61MODULE_PARM_DESC(debug, "Debug level (0-1)");
  62
  63#define dprintk(num, format, args...) \
  64        do { \
  65                if (debug >= num) \
  66                        printk(format, ##args); \
  67        } while (0)
  68
  69/* ----------------------------------------------------------------------- */
  70
  71#define REG_OFFSET      0xDA
  72#define BT856_NR_REG    6
  73
  74struct bt856 {
  75        unsigned char reg[BT856_NR_REG];
  76
  77        int norm;
  78        int enable;
  79};
  80
  81#define   I2C_BT856        0x88
  82
  83/* ----------------------------------------------------------------------- */
  84
  85static inline int
  86bt856_write (struct i2c_client *client,
  87             u8                 reg,
  88             u8                 value)
  89{
  90        struct bt856 *encoder = i2c_get_clientdata(client);
  91
  92        encoder->reg[reg - REG_OFFSET] = value;
  93        return i2c_smbus_write_byte_data(client, reg, value);
  94}
  95
  96static inline int
  97bt856_setbit (struct i2c_client *client,
  98              u8                 reg,
  99              u8                 bit,
 100              u8                 value)
 101{
 102        struct bt856 *encoder = i2c_get_clientdata(client);
 103
 104        return bt856_write(client, reg,
 105                           (encoder->
 106                            reg[reg - REG_OFFSET] & ~(1 << bit)) |
 107                            (value ? (1 << bit) : 0));
 108}
 109
 110static void
 111bt856_dump (struct i2c_client *client)
 112{
 113        int i;
 114        struct bt856 *encoder = i2c_get_clientdata(client);
 115
 116        printk(KERN_INFO "%s: register dump:", I2C_NAME(client));
 117        for (i = 0; i < BT856_NR_REG; i += 2)
 118                printk(" %02x", encoder->reg[i]);
 119        printk("\n");
 120}
 121
 122/* ----------------------------------------------------------------------- */
 123
 124static int
 125bt856_command (struct i2c_client *client,
 126               unsigned int       cmd,
 127               void              *arg)
 128{
 129        struct bt856 *encoder = i2c_get_clientdata(client);
 130
 131        switch (cmd) {
 132
 133        case 0:
 134                /* This is just for testing!!! */
 135                dprintk(1, KERN_INFO "bt856: init\n");
 136                bt856_write(client, 0xdc, 0x18);
 137                bt856_write(client, 0xda, 0);
 138                bt856_write(client, 0xde, 0);
 139
 140                bt856_setbit(client, 0xdc, 3, 1);
 141                //bt856_setbit(client, 0xdc, 6, 0);
 142                bt856_setbit(client, 0xdc, 4, 1);
 143
 144                switch (encoder->norm) {
 145
 146                case VIDEO_MODE_NTSC:
 147                        bt856_setbit(client, 0xdc, 2, 0);
 148                        break;
 149
 150                case VIDEO_MODE_PAL:
 151                        bt856_setbit(client, 0xdc, 2, 1);
 152                        break;
 153                }
 154
 155                bt856_setbit(client, 0xdc, 1, 1);
 156                bt856_setbit(client, 0xde, 4, 0);
 157                bt856_setbit(client, 0xde, 3, 1);
 158                if (debug != 0)
 159                        bt856_dump(client);
 160                break;
 161
 162        case ENCODER_GET_CAPABILITIES:
 163        {
 164                struct video_encoder_capability *cap = arg;
 165
 166                dprintk(1, KERN_INFO "%s: get capabilities\n",
 167                        I2C_NAME(client));
 168
 169                cap->flags = VIDEO_ENCODER_PAL |
 170                             VIDEO_ENCODER_NTSC |
 171                             VIDEO_ENCODER_CCIR;
 172                cap->inputs = 2;
 173                cap->outputs = 1;
 174        }
 175                break;
 176
 177        case ENCODER_SET_NORM:
 178        {
 179                int *iarg = arg;
 180
 181                dprintk(1, KERN_INFO "%s: set norm %d\n", I2C_NAME(client),
 182                        *iarg);
 183
 184                switch (*iarg) {
 185
 186                case VIDEO_MODE_NTSC:
 187                        bt856_setbit(client, 0xdc, 2, 0);
 188                        break;
 189
 190                case VIDEO_MODE_PAL:
 191                        bt856_setbit(client, 0xdc, 2, 1);
 192                        bt856_setbit(client, 0xda, 0, 0);
 193                        //bt856_setbit(client, 0xda, 0, 1);
 194                        break;
 195
 196                default:
 197                        return -EINVAL;
 198
 199                }
 200                encoder->norm = *iarg;
 201                if (debug != 0)
 202                        bt856_dump(client);
 203        }
 204                break;
 205
 206        case ENCODER_SET_INPUT:
 207        {
 208                int *iarg = arg;
 209
 210                dprintk(1, KERN_INFO "%s: set input %d\n", I2C_NAME(client),
 211                        *iarg);
 212
 213                /* We only have video bus.
 214                 * iarg = 0: input is from bt819
 215                 * iarg = 1: input is from ZR36060 */
 216
 217                switch (*iarg) {
 218
 219                case 0:
 220                        bt856_setbit(client, 0xde, 4, 0);
 221                        bt856_setbit(client, 0xde, 3, 1);
 222                        bt856_setbit(client, 0xdc, 3, 1);
 223                        bt856_setbit(client, 0xdc, 6, 0);
 224                        break;
 225                case 1:
 226                        bt856_setbit(client, 0xde, 4, 0);
 227                        bt856_setbit(client, 0xde, 3, 1);
 228                        bt856_setbit(client, 0xdc, 3, 1);
 229                        bt856_setbit(client, 0xdc, 6, 1);
 230                        break;
 231                case 2: // Color bar
 232                        bt856_setbit(client, 0xdc, 3, 0);
 233                        bt856_setbit(client, 0xde, 4, 1);
 234                        break;
 235                default:
 236                        return -EINVAL;
 237
 238                }
 239
 240                if (debug != 0)
 241                        bt856_dump(client);
 242        }
 243                break;
 244
 245        case ENCODER_SET_OUTPUT:
 246        {
 247                int *iarg = arg;
 248
 249                dprintk(1, KERN_INFO "%s: set output %d\n", I2C_NAME(client),
 250                        *iarg);
 251
 252                /* not much choice of outputs */
 253                if (*iarg != 0) {
 254                        return -EINVAL;
 255                }
 256        }
 257                break;
 258
 259        case ENCODER_ENABLE_OUTPUT:
 260        {
 261                int *iarg = arg;
 262
 263                encoder->enable = !!*iarg;
 264
 265                dprintk(1, KERN_INFO "%s: enable output %d\n",
 266                        I2C_NAME(client), encoder->enable);
 267        }
 268                break;
 269
 270        default:
 271                return -EINVAL;
 272        }
 273
 274        return 0;
 275}
 276
 277/* ----------------------------------------------------------------------- */
 278
 279/*
 280 * Generic i2c probe
 281 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
 282 */
 283static unsigned short normal_i2c[] = { I2C_BT856 >> 1, I2C_CLIENT_END };
 284
 285static unsigned short ignore = I2C_CLIENT_END;
 286
 287static struct i2c_client_address_data addr_data = {
 288        .normal_i2c             = normal_i2c,
 289        .probe                  = &ignore,
 290        .ignore                 = &ignore,
 291};
 292
 293static struct i2c_driver i2c_driver_bt856;
 294
 295static int
 296bt856_detect_client (struct i2c_adapter *adapter,
 297                     int                 address,
 298                     int                 kind)
 299{
 300        int i;
 301        struct i2c_client *client;
 302        struct bt856 *encoder;
 303
 304        dprintk(1,
 305                KERN_INFO
 306                "bt856.c: detecting bt856 client on address 0x%x\n",
 307                address << 1);
 308
 309        /* Check if the adapter supports the needed features */
 310        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 311                return 0;
 312
 313        client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
 314        if (client == 0)
 315                return -ENOMEM;
 316        client->addr = address;
 317        client->adapter = adapter;
 318        client->driver = &i2c_driver_bt856;
 319        strlcpy(I2C_NAME(client), "bt856", sizeof(I2C_NAME(client)));
 320
 321        encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL);
 322        if (encoder == NULL) {
 323                kfree(client);
 324                return -ENOMEM;
 325        }
 326        encoder->norm = VIDEO_MODE_NTSC;
 327        encoder->enable = 1;
 328        i2c_set_clientdata(client, encoder);
 329
 330        i = i2c_attach_client(client);
 331        if (i) {
 332                kfree(client);
 333                kfree(encoder);
 334                return i;
 335        }
 336
 337        bt856_write(client, 0xdc, 0x18);
 338        bt856_write(client, 0xda, 0);
 339        bt856_write(client, 0xde, 0);
 340
 341        bt856_setbit(client, 0xdc, 3, 1);
 342        //bt856_setbit(client, 0xdc, 6, 0);
 343        bt856_setbit(client, 0xdc, 4, 1);
 344
 345        switch (encoder->norm) {
 346
 347        case VIDEO_MODE_NTSC:
 348                bt856_setbit(client, 0xdc, 2, 0);
 349                break;
 350
 351        case VIDEO_MODE_PAL:
 352                bt856_setbit(client, 0xdc, 2, 1);
 353                break;
 354        }
 355
 356        bt856_setbit(client, 0xdc, 1, 1);
 357        bt856_setbit(client, 0xde, 4, 0);
 358        bt856_setbit(client, 0xde, 3, 1);
 359
 360        if (debug != 0)
 361                bt856_dump(client);
 362
 363        dprintk(1, KERN_INFO "%s_attach: at address 0x%x\n", I2C_NAME(client),
 364                client->addr << 1);
 365
 366        return 0;
 367}
 368
 369static int
 370bt856_attach_adapter (struct i2c_adapter *adapter)
 371{
 372        dprintk(1,
 373                KERN_INFO
 374                "bt856.c: starting probe for adapter %s (0x%x)\n",
 375                I2C_NAME(adapter), adapter->id);
 376        return i2c_probe(adapter, &addr_data, &bt856_detect_client);
 377}
 378
 379static int
 380bt856_detach_client (struct i2c_client *client)
 381{
 382        struct bt856 *encoder = i2c_get_clientdata(client);
 383        int err;
 384
 385        err = i2c_detach_client(client);
 386        if (err) {
 387                return err;
 388        }
 389
 390        kfree(encoder);
 391        kfree(client);
 392
 393        return 0;
 394}
 395
 396/* ----------------------------------------------------------------------- */
 397
 398static struct i2c_driver i2c_driver_bt856 = {
 399        .driver = {
 400                .name = "bt856",
 401        },
 402
 403        .id = I2C_DRIVERID_BT856,
 404
 405        .attach_adapter = bt856_attach_adapter,
 406        .detach_client = bt856_detach_client,
 407        .command = bt856_command,
 408};
 409
 410static int __init
 411bt856_init (void)
 412{
 413        return i2c_add_driver(&i2c_driver_bt856);
 414}
 415
 416static void __exit
 417bt856_exit (void)
 418{
 419        i2c_del_driver(&i2c_driver_bt856);
 420}
 421
 422module_init(bt856_init);
 423module_exit(bt856_exit);
 424